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(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();
139 virtual ~SubjectQueryImpl() {}
141 SubjectQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
142 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
146 SubjectQueryImpl(const SubjectQueryImpl& src)
147 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
149 if (src.getSubject())
150 setSubject(src.getSubject()->cloneSubject());
153 IMPL_TYPED_CHILD(Subject);
156 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
157 PROC_TYPED_CHILD(Subject,SAML1_NS,true);
158 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
162 class SAML_DLLLOCAL AuthenticationQueryImpl : public virtual AuthenticationQuery, public SubjectQueryImpl
165 m_AuthenticationMethod=nullptr;
168 virtual ~AuthenticationQueryImpl() {
169 XMLString::release(&m_AuthenticationMethod);
172 AuthenticationQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
173 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
177 AuthenticationQueryImpl(const AuthenticationQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
179 setAuthenticationMethod(src.getAuthenticationMethod());
182 IMPL_XMLOBJECT_CLONE(AuthenticationQuery);
183 SubjectQuery* cloneSubjectQuery() const {
184 return cloneAuthenticationQuery();
186 Query* cloneQuery() const {
187 return cloneAuthenticationQuery();
189 IMPL_STRING_ATTRIB(AuthenticationMethod);
192 void marshallAttributes(DOMElement* domElement) const {
193 MARSHALL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,nullptr);
194 SubjectQueryImpl::marshallAttributes(domElement);
197 void processAttribute(const DOMAttr* attribute) {
198 PROC_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,nullptr);
199 SubjectQueryImpl::processAttribute(attribute);
203 class SAML_DLLLOCAL AttributeQueryImpl : public virtual AttributeQuery, public SubjectQueryImpl
209 virtual ~AttributeQueryImpl() {
210 XMLString::release(&m_Resource);
213 AttributeQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
214 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
218 AttributeQueryImpl(const AttributeQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
220 setResource(src.getResource());
221 VectorOf(AttributeDesignator) v=getAttributeDesignators();
222 for (vector<AttributeDesignator*>::const_iterator i=src.m_AttributeDesignators.begin(); i!=src.m_AttributeDesignators.end(); i++) {
224 v.push_back((*i)->cloneAttributeDesignator());
229 IMPL_XMLOBJECT_CLONE(AttributeQuery);
230 SubjectQuery* cloneSubjectQuery() const {
231 return cloneAttributeQuery();
233 Query* cloneQuery() const {
234 return cloneAttributeQuery();
236 IMPL_STRING_ATTRIB(Resource);
237 IMPL_TYPED_CHILDREN(AttributeDesignator,m_children.end());
240 void marshallAttributes(DOMElement* domElement) const {
241 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,nullptr);
242 SubjectQueryImpl::marshallAttributes(domElement);
245 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
246 PROC_TYPED_CHILDREN(AttributeDesignator,SAML1_NS,true);
247 SubjectQueryImpl::processChildElement(childXMLObject,root);
250 void processAttribute(const DOMAttr* attribute) {
251 PROC_STRING_ATTRIB(Resource,RESOURCE,nullptr);
252 SubjectQueryImpl::processAttribute(attribute);
256 class SAML_DLLLOCAL AuthorizationDecisionQueryImpl : public virtual AuthorizationDecisionQuery, public SubjectQueryImpl
261 m_children.push_back(nullptr);
262 m_pos_Evidence=m_pos_Subject;
266 virtual ~AuthorizationDecisionQueryImpl() {
267 XMLString::release(&m_Resource);
270 AuthorizationDecisionQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
271 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
275 AuthorizationDecisionQueryImpl(const AuthorizationDecisionQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
277 setResource(src.getResource());
278 if (src.getEvidence())
279 setEvidence(src.getEvidence()->cloneEvidence());
280 VectorOf(Action) v=getActions();
281 for (vector<Action*>::const_iterator i=src.m_Actions.begin(); i!=src.m_Actions.end(); i++) {
283 v.push_back((*i)->cloneAction());
288 IMPL_XMLOBJECT_CLONE(AuthorizationDecisionQuery);
289 SubjectQuery* cloneSubjectQuery() const {
290 return cloneAuthorizationDecisionQuery();
292 Query* cloneQuery() const {
293 return cloneAuthorizationDecisionQuery();
295 IMPL_STRING_ATTRIB(Resource);
296 IMPL_TYPED_CHILD(Evidence);
297 IMPL_TYPED_CHILDREN(Action, m_pos_Evidence);
300 void marshallAttributes(DOMElement* domElement) const {
301 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,nullptr);
302 SubjectQueryImpl::marshallAttributes(domElement);
305 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
306 PROC_TYPED_CHILD(Evidence,SAML1_NS,false);
307 PROC_TYPED_CHILDREN(Action,SAML1_NS,false);
308 SubjectQueryImpl::processChildElement(childXMLObject,root);
311 void processAttribute(const DOMAttr* attribute) {
312 PROC_STRING_ATTRIB(Resource,RESOURCE,nullptr);
313 SubjectQueryImpl::processAttribute(attribute);
317 class SAML_DLLLOCAL RequestAbstractTypeImpl : public virtual RequestAbstractType,
318 public AbstractComplexElement,
319 public AbstractDOMCachingXMLObject,
320 public AbstractXMLObjectMarshaller,
321 public AbstractXMLObjectUnmarshaller
324 m_MinorVersion=nullptr;
326 m_IssueInstant=nullptr;
327 m_children.push_back(nullptr);
329 m_pos_Signature=m_children.begin();
332 RequestAbstractTypeImpl() {
336 virtual ~RequestAbstractTypeImpl() {
337 XMLString::release(&m_MinorVersion);
338 XMLString::release(&m_RequestID);
339 delete m_IssueInstant;
342 RequestAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
343 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
347 RequestAbstractTypeImpl(const RequestAbstractTypeImpl& src)
348 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
350 setMinorVersion(src.m_MinorVersion);
351 setRequestID(src.getRequestID());
352 setIssueInstant(src.getIssueInstant());
353 if (src.getSignature())
354 setSignature(src.getSignature()->cloneSignature());
355 VectorOf(RespondWith) v=getRespondWiths();
356 for (vector<RespondWith*>::const_iterator i=src.m_RespondWiths.begin(); i!=src.m_RespondWiths.end(); i++) {
358 v.push_back((*i)->cloneRespondWith());
363 //IMPL_TYPED_CHILD(Signature);
364 // Need customized setter.
366 Signature* m_Signature;
367 list<XMLObject*>::iterator m_pos_Signature;
369 Signature* getSignature() const {
373 void setSignature(Signature* sig) {
374 prepareForAssignment(m_Signature,sig);
375 *m_pos_Signature=m_Signature=sig;
376 // Sync content reference back up.
378 m_Signature->setContentReference(new opensaml::ContentReference(*this));
381 IMPL_INTEGER_ATTRIB(MinorVersion);
382 IMPL_STRING_ATTRIB(RequestID); // have to special-case getXMLID
383 const XMLCh* getXMLID() const {
384 pair<bool,int> v = getMinorVersion();
385 return (!v.first || v.second > 0) ? m_RequestID : nullptr;
387 const XMLCh* getID() const {
388 return getRequestID();
390 void releaseDOM() const {
392 getDOM()->removeAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
393 AbstractDOMCachingXMLObject::releaseDOM();
395 IMPL_DATETIME_ATTRIB(IssueInstant,0);
396 IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature);
399 void prepareForMarshalling() const {
401 declareNonVisibleNamespaces();
404 void marshallAttributes(DOMElement* domElement) const {
405 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
406 domElement->setAttributeNS(nullptr,MAJORVERSION,XML_ONE);
408 const_cast<RequestAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
409 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
411 const_cast<RequestAbstractTypeImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
412 domElement->setAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, m_RequestID);
413 if (*m_MinorVersion!=chDigit_0) {
414 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
415 domElement->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, true);
417 domElement->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
420 if (!m_IssueInstant) {
421 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(nullptr);
422 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
424 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
427 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
428 PROC_TYPED_CHILDREN(RespondWith,SAML1P_NS,false);
429 PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
430 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
433 void unmarshallAttributes(const DOMElement* domElement) {
434 // Standard processing, but then we check IDness.
435 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
436 if (m_RequestID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0)) {
437 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
438 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, true);
440 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
445 void processAttribute(const DOMAttr* attribute) {
446 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
447 if (XMLHelper::isNodeNamed(attribute,nullptr,MAJORVERSION)) {
448 if (!XMLString::equals(attribute->getValue(),XML_ONE))
449 throw UnmarshallingException("Request has invalid major version.");
451 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
452 PROC_STRING_ATTRIB(RequestID,REQUESTID,nullptr);
453 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
457 class SAML_DLLLOCAL RequestImpl : public virtual Request, public RequestAbstractTypeImpl
460 m_children.push_back(nullptr);
462 m_pos_Query=m_pos_Signature;
466 virtual ~RequestImpl() {}
468 RequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
469 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
473 RequestImpl(const RequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
476 setQuery(src.getQuery()->cloneQuery());
477 VectorOf(AssertionIDReference) v=getAssertionIDReferences();
478 for (vector<AssertionIDReference*>::const_iterator i=src.m_AssertionIDReferences.begin(); i!=src.m_AssertionIDReferences.end(); i++) {
480 v.push_back((*i)->cloneAssertionIDReference());
483 VectorOf(AssertionArtifact) v2=getAssertionArtifacts();
484 for (vector<AssertionArtifact*>::const_iterator i=src.m_AssertionArtifacts.begin(); i!=src.m_AssertionArtifacts.end(); i++) {
486 v2.push_back((*i)->cloneAssertionArtifact());
491 IMPL_XMLOBJECT_CLONE(Request);
492 RequestAbstractType* cloneRequestAbstractType() const {
493 return cloneRequest();
495 IMPL_TYPED_CHILD(Query);
497 SubjectQuery* getSubjectQuery() const {
498 return dynamic_cast<SubjectQuery*>(getQuery());
500 AuthenticationQuery* getAuthenticationQuery() const {
501 return dynamic_cast<AuthenticationQuery*>(getQuery());
503 AttributeQuery* getAttributeQuery() const {
504 return dynamic_cast<AttributeQuery*>(getQuery());
506 AuthorizationDecisionQuery* getAuthorizationDecisionQuery() const {
507 return dynamic_cast<AuthorizationDecisionQuery*>(getQuery());
510 void setSubjectQuery(SubjectQuery* q) {
513 void setAuthenticationQuery(AuthenticationQuery* q) {
516 void setAttributeQuery(AttributeQuery* q) {
519 void setAuthorizationDecisionQuery(AuthorizationDecisionQuery* q) {
523 IMPL_TYPED_CHILDREN(AssertionIDReference, m_children.end());
524 IMPL_TYPED_CHILDREN(AssertionArtifact, m_children.end());
527 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
528 PROC_TYPED_CHILD(Query,SAML1P_NS,true);
529 PROC_TYPED_CHILDREN(AssertionIDReference,SAML1_NS,false);
530 PROC_TYPED_CHILDREN(AssertionArtifact,SAML1P_NS,false);
531 RequestAbstractTypeImpl::processChildElement(childXMLObject,root);
535 class SAML_DLLLOCAL StatusCodeImpl : public virtual StatusCode,
536 public AbstractComplexElement,
537 public AbstractDOMCachingXMLObject,
538 public AbstractXMLObjectMarshaller,
539 public AbstractXMLObjectUnmarshaller
543 m_children.push_back(nullptr);
544 m_StatusCode=nullptr;
545 m_pos_StatusCode=m_children.begin();
548 virtual ~StatusCodeImpl() {
552 StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
553 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
557 StatusCodeImpl(const StatusCodeImpl& src)
558 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
560 setValue(src.getValue());
561 if (src.getStatusCode())
562 setStatusCode(src.getStatusCode()->cloneStatusCode());
565 IMPL_XMLOBJECT_CLONE(StatusCode);
566 IMPL_XMLOBJECT_ATTRIB(Value,xmltooling::QName);
567 IMPL_TYPED_CHILD(StatusCode);
570 void marshallAttributes(DOMElement* domElement) const {
571 MARSHALL_QNAME_ATTRIB(Value,VALUE,nullptr);
574 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
575 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,true);
576 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
579 void processAttribute(const DOMAttr* attribute) {
580 PROC_QNAME_ATTRIB(Value,VALUE,nullptr);
584 class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail,
585 public AbstractComplexElement,
586 public AbstractDOMCachingXMLObject,
587 public AbstractXMLObjectMarshaller,
588 public AbstractXMLObjectUnmarshaller
591 virtual ~StatusDetailImpl() {}
593 StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
594 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
597 StatusDetailImpl(const StatusDetailImpl& src)
598 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
599 VectorOf(XMLObject) v=getUnknownXMLObjects();
600 for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
601 v.push_back((*i)->clone());
604 IMPL_XMLOBJECT_CLONE(StatusDetail);
605 IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
608 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
609 getUnknownXMLObjects().push_back(childXMLObject);
613 class SAML_DLLLOCAL StatusImpl : public virtual Status,
614 public AbstractComplexElement,
615 public AbstractDOMCachingXMLObject,
616 public AbstractXMLObjectMarshaller,
617 public AbstractXMLObjectUnmarshaller
620 m_children.push_back(nullptr);
621 m_children.push_back(nullptr);
622 m_children.push_back(nullptr);
623 m_StatusCode=nullptr;
624 m_pos_StatusCode=m_children.begin();
625 m_StatusMessage=nullptr;
626 m_pos_StatusMessage=m_pos_StatusCode;
627 ++m_pos_StatusMessage;
628 m_StatusDetail=nullptr;
629 m_pos_StatusDetail=m_pos_StatusMessage;
630 ++m_pos_StatusDetail;
633 virtual ~StatusImpl() {}
635 StatusImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
636 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
640 StatusImpl(const StatusImpl& src)
641 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
643 if (src.getStatusCode())
644 setStatusCode(src.getStatusCode()->cloneStatusCode());
645 if (src.getStatusMessage())
646 setStatusMessage(src.getStatusMessage()->cloneStatusMessage());
647 if (src.getStatusDetail())
648 setStatusDetail(src.getStatusDetail()->cloneStatusDetail());
651 IMPL_XMLOBJECT_CLONE(Status);
652 IMPL_TYPED_CHILD(StatusCode);
653 IMPL_TYPED_CHILD(StatusMessage);
654 IMPL_TYPED_CHILD(StatusDetail);
657 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
658 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,false);
659 PROC_TYPED_CHILD(StatusMessage,SAML1P_NS,false);
660 PROC_TYPED_CHILD(StatusDetail,SAML1P_NS,false);
661 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
665 class SAML_DLLLOCAL ResponseAbstractTypeImpl : public virtual ResponseAbstractType,
666 public AbstractComplexElement,
667 public AbstractDOMCachingXMLObject,
668 public AbstractXMLObjectMarshaller,
669 public AbstractXMLObjectUnmarshaller
672 m_MinorVersion=nullptr;
673 m_ResponseID=nullptr;
674 m_InResponseTo=nullptr;
675 m_IssueInstant=nullptr;
677 m_children.push_back(nullptr);
679 m_pos_Signature=m_children.begin();
682 ResponseAbstractTypeImpl() {
686 virtual ~ResponseAbstractTypeImpl() {
687 XMLString::release(&m_MinorVersion);
688 XMLString::release(&m_ResponseID);
689 XMLString::release(&m_InResponseTo);
690 XMLString::release(&m_Recipient);
691 delete m_IssueInstant;
694 ResponseAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
695 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
699 ResponseAbstractTypeImpl(const ResponseAbstractTypeImpl& src)
700 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
702 setMinorVersion(src.m_MinorVersion);
703 setResponseID(src.getResponseID());
704 setInResponseTo(src.getInResponseTo());
705 setIssueInstant(src.getIssueInstant());
706 setRecipient(src.getRecipient());
707 if (src.getSignature())
708 setSignature(src.getSignature()->cloneSignature());
711 //IMPL_TYPED_CHILD(Signature);
712 // Need customized setter.
714 Signature* m_Signature;
715 list<XMLObject*>::iterator m_pos_Signature;
717 Signature* getSignature() const {
721 void setSignature(Signature* sig) {
722 prepareForAssignment(m_Signature,sig);
723 *m_pos_Signature=m_Signature=sig;
724 // Sync content reference back up.
726 m_Signature->setContentReference(new opensaml::ContentReference(*this));
729 IMPL_INTEGER_ATTRIB(MinorVersion);
730 IMPL_STRING_ATTRIB(ResponseID); // have to special-case getXMLID
731 const XMLCh* getXMLID() const {
732 pair<bool,int> v = getMinorVersion();
733 return (!v.first || v.second > 0) ? m_ResponseID : nullptr;
735 const XMLCh* getID() const {
736 return getResponseID();
738 void releaseDOM() const {
740 getDOM()->removeAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
741 AbstractDOMCachingXMLObject::releaseDOM();
743 IMPL_STRING_ATTRIB(InResponseTo);
744 IMPL_DATETIME_ATTRIB(IssueInstant,0);
745 IMPL_STRING_ATTRIB(Recipient);
748 void prepareForMarshalling() const {
750 declareNonVisibleNamespaces();
753 void marshallAttributes(DOMElement* domElement) const {
754 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
755 domElement->setAttributeNS(nullptr,MAJORVERSION,XML_ONE);
757 const_cast<ResponseAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
758 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
760 const_cast<ResponseAbstractTypeImpl*>(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier();
761 domElement->setAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, m_ResponseID);
762 if (*m_MinorVersion!=chDigit_0) {
763 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
764 domElement->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, true);
766 domElement->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
769 MARSHALL_STRING_ATTRIB(InResponseTo,INRESPONSETO,nullptr);
770 if (!m_IssueInstant) {
771 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(nullptr);
772 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
774 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
775 MARSHALL_STRING_ATTRIB(Recipient,RECIPIENT,nullptr);
778 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
779 PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
780 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
783 void unmarshallAttributes(const DOMElement* domElement) {
784 // Standard processing, but then we check IDness.
785 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
786 if (m_ResponseID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0)) {
787 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
788 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, true);
790 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
795 void processAttribute(const DOMAttr* attribute) {
796 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
797 if (XMLHelper::isNodeNamed(attribute,nullptr,MAJORVERSION)) {
798 if (!XMLString::equals(attribute->getValue(),XML_ONE))
799 throw UnmarshallingException("Response has invalid major version.");
801 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
802 PROC_STRING_ATTRIB(ResponseID,RESPONSEID,nullptr);
803 PROC_STRING_ATTRIB(InResponseTo,INRESPONSETO,nullptr);
804 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
805 PROC_STRING_ATTRIB(Recipient,RECIPIENT,nullptr);
809 class SAML_DLLLOCAL ResponseImpl : public virtual Response, public ResponseAbstractTypeImpl
812 m_children.push_back(nullptr);
814 m_pos_Status=m_pos_Signature;
818 virtual ~ResponseImpl() {}
820 ResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
821 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
825 ResponseImpl(const ResponseImpl& src) : AbstractXMLObject(src), ResponseAbstractTypeImpl(src) {
828 setStatus(src.getStatus()->cloneStatus());
829 VectorOf(saml1::Assertion) v=getAssertions();
830 for (vector<saml1::Assertion*>::const_iterator i=src.m_Assertions.begin(); i!=src.m_Assertions.end(); i++) {
832 v.push_back((*i)->cloneAssertion());
837 IMPL_XMLOBJECT_CLONE(Response);
838 ResponseAbstractType* cloneResponseAbstractType() const {
839 return cloneResponse();
841 IMPL_TYPED_CHILD(Status);
842 IMPL_TYPED_FOREIGN_CHILDREN(Assertion,saml1,m_children.end());
845 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
846 PROC_TYPED_CHILD(Status,SAML1P_NS,false);
847 PROC_TYPED_FOREIGN_CHILDREN(Assertion,saml1,SAML1_NS,true);
848 ResponseAbstractTypeImpl::processChildElement(childXMLObject,root);
855 #if defined (_MSC_VER)
856 #pragma warning( pop )
859 // Builder Implementations
861 IMPL_XMLOBJECTBUILDER(AssertionArtifact);
862 IMPL_XMLOBJECTBUILDER(AttributeQuery);
863 IMPL_XMLOBJECTBUILDER(AuthenticationQuery);
864 IMPL_XMLOBJECTBUILDER(AuthorizationDecisionQuery);
865 IMPL_XMLOBJECTBUILDER(Query);
866 IMPL_XMLOBJECTBUILDER(Request);
867 IMPL_XMLOBJECTBUILDER(RespondWith);
868 IMPL_XMLOBJECTBUILDER(Response);
869 IMPL_XMLOBJECTBUILDER(Status);
870 IMPL_XMLOBJECTBUILDER(StatusCode);
871 IMPL_XMLOBJECTBUILDER(StatusDetail);
872 IMPL_XMLOBJECTBUILDER(StatusMessage);
875 const XMLCh RequestAbstractType::LOCAL_NAME[] = {chNull};
876 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);
877 const XMLCh RequestAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
878 const XMLCh RequestAbstractType::REQUESTID_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,I,D);
879 const XMLCh RequestAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
880 const XMLCh ResponseAbstractType::LOCAL_NAME[] = {chNull};
881 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);
882 const XMLCh ResponseAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
883 const XMLCh ResponseAbstractType::RESPONSEID_ATTRIB_NAME[] = UNICODE_LITERAL_10(R,e,s,p,o,n,s,e,I,D);
884 const XMLCh ResponseAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
885 const XMLCh ResponseAbstractType::INRESPONSETO_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,n,R,e,s,p,o,n,s,e,T,o);
886 const XMLCh ResponseAbstractType::RECIPIENT_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,c,i,p,i,e,n,t);
887 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);
888 const XMLCh AttributeQuery::LOCAL_NAME[] = UNICODE_LITERAL_14(A,t,t,r,i,b,u,t,e,Q,u,e,r,y);
889 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);
890 const XMLCh AttributeQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
891 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);
892 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);
893 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);
894 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);
895 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);
896 const XMLCh AuthorizationDecisionQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
897 const XMLCh Query::LOCAL_NAME[] = UNICODE_LITERAL_5(Q,u,e,r,y);
898 const XMLCh Request::LOCAL_NAME[] = UNICODE_LITERAL_7(R,e,q,u,e,s,t);
899 const XMLCh Request::TYPE_NAME[] = UNICODE_LITERAL_11(R,e,q,u,e,s,t,T,y,p,e);
900 const XMLCh RespondWith::LOCAL_NAME[] = UNICODE_LITERAL_11(R,e,s,p,o,n,d,W,i,t,h);
901 const XMLCh Response::LOCAL_NAME[] = UNICODE_LITERAL_8(R,e,s,p,o,n,s,e);
902 const XMLCh Response::TYPE_NAME[] = UNICODE_LITERAL_12(R,e,s,p,o,n,s,e,T,y,p,e);
903 const XMLCh Status::LOCAL_NAME[] = UNICODE_LITERAL_6(S,t,a,t,u,s);
904 const XMLCh Status::TYPE_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,T,y,p,e);
905 const XMLCh StatusCode::LOCAL_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,C,o,d,e);
906 const XMLCh StatusCode::TYPE_NAME[] = UNICODE_LITERAL_14(S,t,a,t,u,s,C,o,d,e,T,y,p,e);
907 const XMLCh StatusCode::VALUE_ATTRIB_NAME[] = UNICODE_LITERAL_5(V,a,l,u,e);
908 const XMLCh StatusDetail::LOCAL_NAME[] = UNICODE_LITERAL_12(S,t,a,t,u,s,D,e,t,a,i,l);
909 const XMLCh StatusDetail::TYPE_NAME[] = UNICODE_LITERAL_16(S,t,a,t,u,s,D,e,t,a,i,l,T,y,p,e);
910 const XMLCh StatusMessage::LOCAL_NAME[] = UNICODE_LITERAL_13(S,t,a,t,u,s,M,e,s,s,a,g,e);
911 const XMLCh SubjectQuery::LOCAL_NAME[] = UNICODE_LITERAL_12(S,u,b,j,e,c,t,Q,u,e,r,y);
913 #define XCH(ch) chLatin_##ch
914 #define XNUM(d) chDigit_##d
916 const XMLCh _SUCCESS[] = UNICODE_LITERAL_7(S,u,c,c,e,s,s);
917 const XMLCh _REQUESTER[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,e,r);
918 const XMLCh _RESPONDER[] = UNICODE_LITERAL_9(R,e,s,p,o,n,d,e,r);
919 const XMLCh _VERSIONMISMATCH[] = UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h);
921 xmltooling::QName StatusCode::SUCCESS(SAML1P_NS,_SUCCESS,SAML1P_PREFIX);
922 xmltooling::QName StatusCode::REQUESTER(SAML1P_NS,_REQUESTER,SAML1P_PREFIX);
923 xmltooling::QName StatusCode::RESPONDER(SAML1P_NS,_RESPONDER,SAML1P_PREFIX);
924 xmltooling::QName StatusCode::VERSIONMISMATCH(SAML1P_NS,_VERSIONMISMATCH,SAML1P_PREFIX);