2 * Copyright 2001-2010 Internet2
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 * Implementation classes for SAML 1.x Protocols schema.
24 #include "exceptions.h"
25 #include "saml1/core/Assertions.h"
26 #include "saml1/core/Protocols.h"
27 #include "signature/ContentReference.h"
29 #include <xmltooling/AbstractComplexElement.h>
30 #include <xmltooling/AbstractSimpleElement.h>
31 #include <xmltooling/impl/AnyElement.h>
32 #include <xmltooling/io/AbstractXMLObjectMarshaller.h>
33 #include <xmltooling/io/AbstractXMLObjectUnmarshaller.h>
34 #include <xmltooling/signature/Signature.h>
35 #include <xmltooling/util/DateTime.h>
36 #include <xmltooling/util/XMLHelper.h>
39 #include <xercesc/util/XMLUniDefs.hpp>
41 using namespace opensaml::saml1p;
42 using namespace opensaml::saml1;
43 using namespace xmlsignature;
44 using namespace xmltooling;
46 using xmlconstants::XMLSIG_NS;
47 using xmlconstants::XML_ONE;
48 using samlconstants::SAML1P_NS;
49 using samlconstants::SAML1_NS;
50 using samlconstants::SAML1P_PREFIX;
52 #if defined (_MSC_VER)
53 #pragma warning( push )
54 #pragma warning( disable : 4250 4251 )
60 DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,AssertionArtifact);
61 DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,StatusMessage);
63 class SAML_DLLLOCAL RespondWithImpl : public virtual RespondWith,
64 public AbstractSimpleElement,
65 public AbstractDOMCachingXMLObject,
66 public AbstractXMLObjectMarshaller,
67 public AbstractXMLObjectUnmarshaller
69 mutable xmltooling::QName* m_qname;
71 virtual ~RespondWithImpl() {
75 RespondWithImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
76 : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_qname(nullptr) {
79 RespondWithImpl(const RespondWithImpl& src)
80 : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src), m_qname(nullptr) {
81 setQName(src.getQName());
84 xmltooling::QName* getQName() const {
85 if (!m_qname && getDOM() && getDOM()->getTextContent()) {
86 m_qname = XMLHelper::getNodeValueAsQName(getDOM());
91 void setQName(const xmltooling::QName* qname) {
92 m_qname=prepareForAssignment(m_qname,qname);
94 auto_ptr_XMLCh temp(m_qname->toString().c_str());
95 setTextContent(temp.get());
98 setTextContent(nullptr);
102 IMPL_XMLOBJECT_CLONE(RespondWith);
105 class SAML_DLLLOCAL QueryImpl : public virtual Query, public AnyElementImpl
108 virtual ~QueryImpl() {}
110 QueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
111 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
114 QueryImpl(const QueryImpl& src) : AbstractXMLObject(src), AnyElementImpl(src) {}
116 IMPL_XMLOBJECT_CLONE(Query);
119 class SAML_DLLLOCAL SubjectQueryImpl : public virtual SubjectQuery,
120 public AbstractComplexElement,
121 public AbstractDOMCachingXMLObject,
122 public AbstractXMLObjectMarshaller,
123 public AbstractXMLObjectUnmarshaller
127 m_children.push_back(nullptr);
128 m_pos_Subject=m_children.begin();
135 virtual ~SubjectQueryImpl() {}
137 SubjectQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
138 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
142 SubjectQueryImpl(const SubjectQueryImpl& src)
143 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
145 if (src.getSubject())
146 setSubject(src.getSubject()->cloneSubject());
149 IMPL_TYPED_CHILD(Subject);
152 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
153 PROC_TYPED_CHILD(Subject,SAML1_NS,true);
154 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
158 class SAML_DLLLOCAL AuthenticationQueryImpl : public virtual AuthenticationQuery, public SubjectQueryImpl
161 m_AuthenticationMethod=nullptr;
164 virtual ~AuthenticationQueryImpl() {
165 XMLString::release(&m_AuthenticationMethod);
168 AuthenticationQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
169 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
173 AuthenticationQueryImpl(const AuthenticationQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
175 setAuthenticationMethod(src.getAuthenticationMethod());
178 IMPL_XMLOBJECT_CLONE(AuthenticationQuery);
179 SubjectQuery* cloneSubjectQuery() const {
180 return cloneAuthenticationQuery();
182 Query* cloneQuery() const {
183 return cloneAuthenticationQuery();
185 IMPL_STRING_ATTRIB(AuthenticationMethod);
188 void marshallAttributes(DOMElement* domElement) const {
189 MARSHALL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,nullptr);
190 SubjectQueryImpl::marshallAttributes(domElement);
193 void processAttribute(const DOMAttr* attribute) {
194 PROC_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,nullptr);
195 SubjectQueryImpl::processAttribute(attribute);
199 class SAML_DLLLOCAL AttributeQueryImpl : public virtual AttributeQuery, public SubjectQueryImpl
205 virtual ~AttributeQueryImpl() {
206 XMLString::release(&m_Resource);
209 AttributeQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
210 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
214 AttributeQueryImpl(const AttributeQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
216 setResource(src.getResource());
217 VectorOf(AttributeDesignator) v=getAttributeDesignators();
218 for (vector<AttributeDesignator*>::const_iterator i=src.m_AttributeDesignators.begin(); i!=src.m_AttributeDesignators.end(); i++) {
220 v.push_back((*i)->cloneAttributeDesignator());
225 IMPL_XMLOBJECT_CLONE(AttributeQuery);
226 SubjectQuery* cloneSubjectQuery() const {
227 return cloneAttributeQuery();
229 Query* cloneQuery() const {
230 return cloneAttributeQuery();
232 IMPL_STRING_ATTRIB(Resource);
233 IMPL_TYPED_CHILDREN(AttributeDesignator,m_children.end());
236 void marshallAttributes(DOMElement* domElement) const {
237 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,nullptr);
238 SubjectQueryImpl::marshallAttributes(domElement);
241 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
242 PROC_TYPED_CHILDREN(AttributeDesignator,SAML1_NS,true);
243 SubjectQueryImpl::processChildElement(childXMLObject,root);
246 void processAttribute(const DOMAttr* attribute) {
247 PROC_STRING_ATTRIB(Resource,RESOURCE,nullptr);
248 SubjectQueryImpl::processAttribute(attribute);
252 class SAML_DLLLOCAL AuthorizationDecisionQueryImpl : public virtual AuthorizationDecisionQuery, public SubjectQueryImpl
257 m_children.push_back(nullptr);
258 m_pos_Evidence=m_pos_Subject;
262 virtual ~AuthorizationDecisionQueryImpl() {
263 XMLString::release(&m_Resource);
266 AuthorizationDecisionQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
267 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
271 AuthorizationDecisionQueryImpl(const AuthorizationDecisionQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
273 setResource(src.getResource());
274 if (src.getEvidence())
275 setEvidence(src.getEvidence()->cloneEvidence());
276 VectorOf(Action) v=getActions();
277 for (vector<Action*>::const_iterator i=src.m_Actions.begin(); i!=src.m_Actions.end(); i++) {
279 v.push_back((*i)->cloneAction());
284 IMPL_XMLOBJECT_CLONE(AuthorizationDecisionQuery);
285 SubjectQuery* cloneSubjectQuery() const {
286 return cloneAuthorizationDecisionQuery();
288 Query* cloneQuery() const {
289 return cloneAuthorizationDecisionQuery();
291 IMPL_STRING_ATTRIB(Resource);
292 IMPL_TYPED_CHILD(Evidence);
293 IMPL_TYPED_CHILDREN(Action, m_pos_Evidence);
296 void marshallAttributes(DOMElement* domElement) const {
297 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,nullptr);
298 SubjectQueryImpl::marshallAttributes(domElement);
301 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
302 PROC_TYPED_CHILD(Evidence,SAML1_NS,false);
303 PROC_TYPED_CHILDREN(Action,SAML1_NS,false);
304 SubjectQueryImpl::processChildElement(childXMLObject,root);
307 void processAttribute(const DOMAttr* attribute) {
308 PROC_STRING_ATTRIB(Resource,RESOURCE,nullptr);
309 SubjectQueryImpl::processAttribute(attribute);
313 class SAML_DLLLOCAL RequestAbstractTypeImpl : public virtual RequestAbstractType,
314 public AbstractComplexElement,
315 public AbstractDOMCachingXMLObject,
316 public AbstractXMLObjectMarshaller,
317 public AbstractXMLObjectUnmarshaller
320 m_MinorVersion=nullptr;
322 m_IssueInstant=nullptr;
323 m_children.push_back(nullptr);
325 m_pos_Signature=m_children.begin();
328 RequestAbstractTypeImpl() {
332 virtual ~RequestAbstractTypeImpl() {
333 XMLString::release(&m_MinorVersion);
334 XMLString::release(&m_RequestID);
335 delete m_IssueInstant;
338 RequestAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
339 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
343 RequestAbstractTypeImpl(const RequestAbstractTypeImpl& src)
344 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
346 setMinorVersion(src.m_MinorVersion);
347 setRequestID(src.getRequestID());
348 setIssueInstant(src.getIssueInstant());
349 if (src.getSignature())
350 setSignature(src.getSignature()->cloneSignature());
351 VectorOf(RespondWith) v=getRespondWiths();
352 for (vector<RespondWith*>::const_iterator i=src.m_RespondWiths.begin(); i!=src.m_RespondWiths.end(); i++) {
354 v.push_back((*i)->cloneRespondWith());
359 //IMPL_TYPED_CHILD(Signature);
360 // Need customized setter.
362 Signature* m_Signature;
363 list<XMLObject*>::iterator m_pos_Signature;
365 Signature* getSignature() const {
369 void setSignature(Signature* sig) {
370 prepareForAssignment(m_Signature,sig);
371 *m_pos_Signature=m_Signature=sig;
372 // Sync content reference back up.
374 m_Signature->setContentReference(new opensaml::ContentReference(*this));
377 IMPL_INTEGER_ATTRIB(MinorVersion);
378 IMPL_STRING_ATTRIB(RequestID); // have to special-case getXMLID
379 const XMLCh* getXMLID() const {
380 pair<bool,int> v = getMinorVersion();
381 return (!v.first || v.second > 0) ? m_RequestID : nullptr;
383 const XMLCh* getID() const {
384 return getRequestID();
386 void releaseDOM() const {
388 getDOM()->removeAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
389 AbstractDOMCachingXMLObject::releaseDOM();
391 IMPL_DATETIME_ATTRIB(IssueInstant,0);
392 IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature);
395 void prepareForMarshalling() const {
397 declareNonVisibleNamespaces();
400 void marshallAttributes(DOMElement* domElement) const {
401 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
402 domElement->setAttributeNS(nullptr,MAJORVERSION,XML_ONE);
404 const_cast<RequestAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
405 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
407 const_cast<RequestAbstractTypeImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
408 domElement->setAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, m_RequestID);
409 if (*m_MinorVersion!=chDigit_0) {
410 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
411 domElement->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, true);
413 domElement->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
416 if (!m_IssueInstant) {
417 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(nullptr);
418 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
420 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
423 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
424 PROC_TYPED_CHILDREN(RespondWith,SAML1P_NS,false);
425 PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
426 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
429 void unmarshallAttributes(const DOMElement* domElement) {
430 // Standard processing, but then we check IDness.
431 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
432 if (m_RequestID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0)) {
433 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
434 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, true);
436 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
441 void processAttribute(const DOMAttr* attribute) {
442 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
443 if (XMLHelper::isNodeNamed(attribute,nullptr,MAJORVERSION)) {
444 if (!XMLString::equals(attribute->getValue(),XML_ONE))
445 throw UnmarshallingException("Request has invalid major version.");
447 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
448 PROC_STRING_ATTRIB(RequestID,REQUESTID,nullptr);
449 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
453 class SAML_DLLLOCAL RequestImpl : public virtual Request, public RequestAbstractTypeImpl
456 m_children.push_back(nullptr);
458 m_pos_Query=m_pos_Signature;
462 virtual ~RequestImpl() {}
464 RequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
465 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
469 RequestImpl(const RequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
472 setQuery(src.getQuery()->cloneQuery());
473 VectorOf(AssertionIDReference) v=getAssertionIDReferences();
474 for (vector<AssertionIDReference*>::const_iterator i=src.m_AssertionIDReferences.begin(); i!=src.m_AssertionIDReferences.end(); i++) {
476 v.push_back((*i)->cloneAssertionIDReference());
479 VectorOf(AssertionArtifact) v2=getAssertionArtifacts();
480 for (vector<AssertionArtifact*>::const_iterator i=src.m_AssertionArtifacts.begin(); i!=src.m_AssertionArtifacts.end(); i++) {
482 v2.push_back((*i)->cloneAssertionArtifact());
487 IMPL_XMLOBJECT_CLONE(Request);
488 RequestAbstractType* cloneRequestAbstractType() const {
489 return cloneRequest();
491 IMPL_TYPED_CHILD(Query);
493 SubjectQuery* getSubjectQuery() const {
494 return dynamic_cast<SubjectQuery*>(getQuery());
496 AuthenticationQuery* getAuthenticationQuery() const {
497 return dynamic_cast<AuthenticationQuery*>(getQuery());
499 AttributeQuery* getAttributeQuery() const {
500 return dynamic_cast<AttributeQuery*>(getQuery());
502 AuthorizationDecisionQuery* getAuthorizationDecisionQuery() const {
503 return dynamic_cast<AuthorizationDecisionQuery*>(getQuery());
506 void setSubjectQuery(SubjectQuery* q) {
509 void setAuthenticationQuery(AuthenticationQuery* q) {
512 void setAttributeQuery(AttributeQuery* q) {
515 void setAuthorizationDecisionQuery(AuthorizationDecisionQuery* q) {
519 IMPL_TYPED_CHILDREN(AssertionIDReference, m_children.end());
520 IMPL_TYPED_CHILDREN(AssertionArtifact, m_children.end());
523 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
524 PROC_TYPED_CHILD(Query,SAML1P_NS,true);
525 PROC_TYPED_CHILDREN(AssertionIDReference,SAML1_NS,false);
526 PROC_TYPED_CHILDREN(AssertionArtifact,SAML1P_NS,false);
527 RequestAbstractTypeImpl::processChildElement(childXMLObject,root);
531 class SAML_DLLLOCAL StatusCodeImpl : public virtual StatusCode,
532 public AbstractComplexElement,
533 public AbstractDOMCachingXMLObject,
534 public AbstractXMLObjectMarshaller,
535 public AbstractXMLObjectUnmarshaller
539 m_children.push_back(nullptr);
540 m_StatusCode=nullptr;
541 m_pos_StatusCode=m_children.begin();
544 virtual ~StatusCodeImpl() {
548 StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
549 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
553 StatusCodeImpl(const StatusCodeImpl& src)
554 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
556 setValue(src.getValue());
557 if (src.getStatusCode())
558 setStatusCode(src.getStatusCode()->cloneStatusCode());
561 IMPL_XMLOBJECT_CLONE(StatusCode);
562 IMPL_XMLOBJECT_ATTRIB(Value,xmltooling::QName);
563 IMPL_TYPED_CHILD(StatusCode);
566 void marshallAttributes(DOMElement* domElement) const {
567 MARSHALL_QNAME_ATTRIB(Value,VALUE,nullptr);
570 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
571 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,true);
572 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
575 void processAttribute(const DOMAttr* attribute) {
576 PROC_QNAME_ATTRIB(Value,VALUE,nullptr);
580 class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail,
581 public AbstractComplexElement,
582 public AbstractDOMCachingXMLObject,
583 public AbstractXMLObjectMarshaller,
584 public AbstractXMLObjectUnmarshaller
587 virtual ~StatusDetailImpl() {}
589 StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
590 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
593 StatusDetailImpl(const StatusDetailImpl& src)
594 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
595 VectorOf(XMLObject) v=getUnknownXMLObjects();
596 for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
597 v.push_back((*i)->clone());
600 IMPL_XMLOBJECT_CLONE(StatusDetail);
601 IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
604 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
605 getUnknownXMLObjects().push_back(childXMLObject);
609 class SAML_DLLLOCAL StatusImpl : public virtual Status,
610 public AbstractComplexElement,
611 public AbstractDOMCachingXMLObject,
612 public AbstractXMLObjectMarshaller,
613 public AbstractXMLObjectUnmarshaller
616 m_children.push_back(nullptr);
617 m_children.push_back(nullptr);
618 m_children.push_back(nullptr);
619 m_StatusCode=nullptr;
620 m_pos_StatusCode=m_children.begin();
621 m_StatusMessage=nullptr;
622 m_pos_StatusMessage=m_pos_StatusCode;
623 ++m_pos_StatusMessage;
624 m_StatusDetail=nullptr;
625 m_pos_StatusDetail=m_pos_StatusMessage;
626 ++m_pos_StatusDetail;
629 virtual ~StatusImpl() {}
631 StatusImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
632 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
636 StatusImpl(const StatusImpl& src)
637 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
639 if (src.getStatusCode())
640 setStatusCode(src.getStatusCode()->cloneStatusCode());
641 if (src.getStatusMessage())
642 setStatusMessage(src.getStatusMessage()->cloneStatusMessage());
643 if (src.getStatusDetail())
644 setStatusDetail(src.getStatusDetail()->cloneStatusDetail());
647 IMPL_XMLOBJECT_CLONE(Status);
648 IMPL_TYPED_CHILD(StatusCode);
649 IMPL_TYPED_CHILD(StatusMessage);
650 IMPL_TYPED_CHILD(StatusDetail);
653 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
654 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,false);
655 PROC_TYPED_CHILD(StatusMessage,SAML1P_NS,false);
656 PROC_TYPED_CHILD(StatusDetail,SAML1P_NS,false);
657 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
661 class SAML_DLLLOCAL ResponseAbstractTypeImpl : public virtual ResponseAbstractType,
662 public AbstractComplexElement,
663 public AbstractDOMCachingXMLObject,
664 public AbstractXMLObjectMarshaller,
665 public AbstractXMLObjectUnmarshaller
668 m_MinorVersion=nullptr;
669 m_ResponseID=nullptr;
670 m_InResponseTo=nullptr;
671 m_IssueInstant=nullptr;
673 m_children.push_back(nullptr);
675 m_pos_Signature=m_children.begin();
678 ResponseAbstractTypeImpl() {
682 virtual ~ResponseAbstractTypeImpl() {
683 XMLString::release(&m_MinorVersion);
684 XMLString::release(&m_ResponseID);
685 XMLString::release(&m_InResponseTo);
686 XMLString::release(&m_Recipient);
687 delete m_IssueInstant;
690 ResponseAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
691 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
695 ResponseAbstractTypeImpl(const ResponseAbstractTypeImpl& src)
696 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
698 setMinorVersion(src.m_MinorVersion);
699 setResponseID(src.getResponseID());
700 setInResponseTo(src.getInResponseTo());
701 setIssueInstant(src.getIssueInstant());
702 setRecipient(src.getRecipient());
703 if (src.getSignature())
704 setSignature(src.getSignature()->cloneSignature());
707 //IMPL_TYPED_CHILD(Signature);
708 // Need customized setter.
710 Signature* m_Signature;
711 list<XMLObject*>::iterator m_pos_Signature;
713 Signature* getSignature() const {
717 void setSignature(Signature* sig) {
718 prepareForAssignment(m_Signature,sig);
719 *m_pos_Signature=m_Signature=sig;
720 // Sync content reference back up.
722 m_Signature->setContentReference(new opensaml::ContentReference(*this));
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_CHILD(Signature,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;
814 virtual ~ResponseImpl() {}
816 ResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
817 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
821 ResponseImpl(const ResponseImpl& src) : AbstractXMLObject(src), ResponseAbstractTypeImpl(src) {
824 setStatus(src.getStatus()->cloneStatus());
825 VectorOf(saml1::Assertion) v=getAssertions();
826 for (vector<saml1::Assertion*>::const_iterator i=src.m_Assertions.begin(); i!=src.m_Assertions.end(); i++) {
828 v.push_back((*i)->cloneAssertion());
833 IMPL_XMLOBJECT_CLONE(Response);
834 ResponseAbstractType* cloneResponseAbstractType() const {
835 return cloneResponse();
837 IMPL_TYPED_CHILD(Status);
838 IMPL_TYPED_FOREIGN_CHILDREN(Assertion,saml1,m_children.end());
841 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
842 PROC_TYPED_CHILD(Status,SAML1P_NS,false);
843 PROC_TYPED_FOREIGN_CHILDREN(Assertion,saml1,SAML1_NS,true);
844 ResponseAbstractTypeImpl::processChildElement(childXMLObject,root);
851 #if defined (_MSC_VER)
852 #pragma warning( pop )
855 // Builder Implementations
857 IMPL_XMLOBJECTBUILDER(AssertionArtifact);
858 IMPL_XMLOBJECTBUILDER(AttributeQuery);
859 IMPL_XMLOBJECTBUILDER(AuthenticationQuery);
860 IMPL_XMLOBJECTBUILDER(AuthorizationDecisionQuery);
861 IMPL_XMLOBJECTBUILDER(Query);
862 IMPL_XMLOBJECTBUILDER(Request);
863 IMPL_XMLOBJECTBUILDER(RespondWith);
864 IMPL_XMLOBJECTBUILDER(Response);
865 IMPL_XMLOBJECTBUILDER(Status);
866 IMPL_XMLOBJECTBUILDER(StatusCode);
867 IMPL_XMLOBJECTBUILDER(StatusDetail);
868 IMPL_XMLOBJECTBUILDER(StatusMessage);
871 const XMLCh RequestAbstractType::LOCAL_NAME[] = {chNull};
872 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);
873 const XMLCh RequestAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
874 const XMLCh RequestAbstractType::REQUESTID_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,I,D);
875 const XMLCh RequestAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
876 const XMLCh ResponseAbstractType::LOCAL_NAME[] = {chNull};
877 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);
878 const XMLCh ResponseAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
879 const XMLCh ResponseAbstractType::RESPONSEID_ATTRIB_NAME[] = UNICODE_LITERAL_10(R,e,s,p,o,n,s,e,I,D);
880 const XMLCh ResponseAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
881 const XMLCh ResponseAbstractType::INRESPONSETO_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,n,R,e,s,p,o,n,s,e,T,o);
882 const XMLCh ResponseAbstractType::RECIPIENT_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,c,i,p,i,e,n,t);
883 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);
884 const XMLCh AttributeQuery::LOCAL_NAME[] = UNICODE_LITERAL_14(A,t,t,r,i,b,u,t,e,Q,u,e,r,y);
885 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);
886 const XMLCh AttributeQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
887 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);
888 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);
889 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);
890 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);
891 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);
892 const XMLCh AuthorizationDecisionQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
893 const XMLCh Query::LOCAL_NAME[] = UNICODE_LITERAL_5(Q,u,e,r,y);
894 const XMLCh Request::LOCAL_NAME[] = UNICODE_LITERAL_7(R,e,q,u,e,s,t);
895 const XMLCh Request::TYPE_NAME[] = UNICODE_LITERAL_11(R,e,q,u,e,s,t,T,y,p,e);
896 const XMLCh RespondWith::LOCAL_NAME[] = UNICODE_LITERAL_11(R,e,s,p,o,n,d,W,i,t,h);
897 const XMLCh Response::LOCAL_NAME[] = UNICODE_LITERAL_8(R,e,s,p,o,n,s,e);
898 const XMLCh Response::TYPE_NAME[] = UNICODE_LITERAL_12(R,e,s,p,o,n,s,e,T,y,p,e);
899 const XMLCh Status::LOCAL_NAME[] = UNICODE_LITERAL_6(S,t,a,t,u,s);
900 const XMLCh Status::TYPE_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,T,y,p,e);
901 const XMLCh StatusCode::LOCAL_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,C,o,d,e);
902 const XMLCh StatusCode::TYPE_NAME[] = UNICODE_LITERAL_14(S,t,a,t,u,s,C,o,d,e,T,y,p,e);
903 const XMLCh StatusCode::VALUE_ATTRIB_NAME[] = UNICODE_LITERAL_5(V,a,l,u,e);
904 const XMLCh StatusDetail::LOCAL_NAME[] = UNICODE_LITERAL_12(S,t,a,t,u,s,D,e,t,a,i,l);
905 const XMLCh StatusDetail::TYPE_NAME[] = UNICODE_LITERAL_16(S,t,a,t,u,s,D,e,t,a,i,l,T,y,p,e);
906 const XMLCh StatusMessage::LOCAL_NAME[] = UNICODE_LITERAL_13(S,t,a,t,u,s,M,e,s,s,a,g,e);
907 const XMLCh SubjectQuery::LOCAL_NAME[] = UNICODE_LITERAL_12(S,u,b,j,e,c,t,Q,u,e,r,y);
909 #define XCH(ch) chLatin_##ch
910 #define XNUM(d) chDigit_##d
912 const XMLCh _SUCCESS[] = UNICODE_LITERAL_7(S,u,c,c,e,s,s);
913 const XMLCh _REQUESTER[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,e,r);
914 const XMLCh _RESPONDER[] = UNICODE_LITERAL_9(R,e,s,p,o,n,d,e,r);
915 const XMLCh _VERSIONMISMATCH[] = UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h);
917 xmltooling::QName StatusCode::SUCCESS(SAML1P_NS,_SUCCESS,SAML1P_PREFIX);
918 xmltooling::QName StatusCode::REQUESTER(SAML1P_NS,_REQUESTER,SAML1P_PREFIX);
919 xmltooling::QName StatusCode::RESPONDER(SAML1P_NS,_RESPONDER,SAML1P_PREFIX);
920 xmltooling::QName StatusCode::VERSIONMISMATCH(SAML1P_NS,_VERSIONMISMATCH,SAML1P_PREFIX);