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 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 {
88 void setQName(const xmltooling::QName* qname) {
89 m_qname=prepareForAssignment(m_qname,qname);
91 auto_ptr_XMLCh temp(m_qname->toString().c_str());
92 setTextContent(temp.get());
95 setTextContent(nullptr);
98 IMPL_XMLOBJECT_CLONE(RespondWith);
101 class SAML_DLLLOCAL QueryImpl : public virtual Query, public AnyElementImpl
104 virtual ~QueryImpl() {}
106 QueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
107 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
110 QueryImpl(const QueryImpl& src) : AbstractXMLObject(src), AnyElementImpl(src) {}
112 IMPL_XMLOBJECT_CLONE(Query);
115 class SAML_DLLLOCAL SubjectQueryImpl : public virtual SubjectQuery,
116 public AbstractComplexElement,
117 public AbstractDOMCachingXMLObject,
118 public AbstractXMLObjectMarshaller,
119 public AbstractXMLObjectUnmarshaller
123 m_children.push_back(nullptr);
124 m_pos_Subject=m_children.begin();
131 virtual ~SubjectQueryImpl() {}
133 SubjectQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
134 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
138 SubjectQueryImpl(const SubjectQueryImpl& src)
139 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
141 if (src.getSubject())
142 setSubject(src.getSubject()->cloneSubject());
145 IMPL_TYPED_CHILD(Subject);
148 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
149 PROC_TYPED_CHILD(Subject,SAML1_NS,true);
150 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
154 class SAML_DLLLOCAL AuthenticationQueryImpl : public virtual AuthenticationQuery, public SubjectQueryImpl
157 m_AuthenticationMethod=nullptr;
160 virtual ~AuthenticationQueryImpl() {
161 XMLString::release(&m_AuthenticationMethod);
164 AuthenticationQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
165 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
169 AuthenticationQueryImpl(const AuthenticationQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
171 setAuthenticationMethod(src.getAuthenticationMethod());
174 IMPL_XMLOBJECT_CLONE(AuthenticationQuery);
175 SubjectQuery* cloneSubjectQuery() const {
176 return cloneAuthenticationQuery();
178 Query* cloneQuery() const {
179 return cloneAuthenticationQuery();
181 IMPL_STRING_ATTRIB(AuthenticationMethod);
184 void marshallAttributes(DOMElement* domElement) const {
185 MARSHALL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,nullptr);
186 SubjectQueryImpl::marshallAttributes(domElement);
189 void processAttribute(const DOMAttr* attribute) {
190 PROC_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,nullptr);
191 SubjectQueryImpl::processAttribute(attribute);
195 class SAML_DLLLOCAL AttributeQueryImpl : public virtual AttributeQuery, public SubjectQueryImpl
201 virtual ~AttributeQueryImpl() {
202 XMLString::release(&m_Resource);
205 AttributeQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
206 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
210 AttributeQueryImpl(const AttributeQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
212 setResource(src.getResource());
213 VectorOf(AttributeDesignator) v=getAttributeDesignators();
214 for (vector<AttributeDesignator*>::const_iterator i=src.m_AttributeDesignators.begin(); i!=src.m_AttributeDesignators.end(); i++) {
216 v.push_back((*i)->cloneAttributeDesignator());
221 IMPL_XMLOBJECT_CLONE(AttributeQuery);
222 SubjectQuery* cloneSubjectQuery() const {
223 return cloneAttributeQuery();
225 Query* cloneQuery() const {
226 return cloneAttributeQuery();
228 IMPL_STRING_ATTRIB(Resource);
229 IMPL_TYPED_CHILDREN(AttributeDesignator,m_children.end());
232 void marshallAttributes(DOMElement* domElement) const {
233 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,nullptr);
234 SubjectQueryImpl::marshallAttributes(domElement);
237 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
238 PROC_TYPED_CHILDREN(AttributeDesignator,SAML1_NS,true);
239 SubjectQueryImpl::processChildElement(childXMLObject,root);
242 void processAttribute(const DOMAttr* attribute) {
243 PROC_STRING_ATTRIB(Resource,RESOURCE,nullptr);
244 SubjectQueryImpl::processAttribute(attribute);
248 class SAML_DLLLOCAL AuthorizationDecisionQueryImpl : public virtual AuthorizationDecisionQuery, public SubjectQueryImpl
253 m_children.push_back(nullptr);
254 m_pos_Evidence=m_pos_Subject;
258 virtual ~AuthorizationDecisionQueryImpl() {
259 XMLString::release(&m_Resource);
262 AuthorizationDecisionQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
263 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
267 AuthorizationDecisionQueryImpl(const AuthorizationDecisionQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
269 setResource(src.getResource());
270 if (src.getEvidence())
271 setEvidence(src.getEvidence()->cloneEvidence());
272 VectorOf(Action) v=getActions();
273 for (vector<Action*>::const_iterator i=src.m_Actions.begin(); i!=src.m_Actions.end(); i++) {
275 v.push_back((*i)->cloneAction());
280 IMPL_XMLOBJECT_CLONE(AuthorizationDecisionQuery);
281 SubjectQuery* cloneSubjectQuery() const {
282 return cloneAuthorizationDecisionQuery();
284 Query* cloneQuery() const {
285 return cloneAuthorizationDecisionQuery();
287 IMPL_STRING_ATTRIB(Resource);
288 IMPL_TYPED_CHILD(Evidence);
289 IMPL_TYPED_CHILDREN(Action, m_pos_Evidence);
292 void marshallAttributes(DOMElement* domElement) const {
293 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,nullptr);
294 SubjectQueryImpl::marshallAttributes(domElement);
297 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
298 PROC_TYPED_CHILD(Evidence,SAML1_NS,false);
299 PROC_TYPED_CHILDREN(Action,SAML1_NS,false);
300 SubjectQueryImpl::processChildElement(childXMLObject,root);
303 void processAttribute(const DOMAttr* attribute) {
304 PROC_STRING_ATTRIB(Resource,RESOURCE,nullptr);
305 SubjectQueryImpl::processAttribute(attribute);
309 class SAML_DLLLOCAL RequestAbstractTypeImpl : public virtual RequestAbstractType,
310 public AbstractComplexElement,
311 public AbstractDOMCachingXMLObject,
312 public AbstractXMLObjectMarshaller,
313 public AbstractXMLObjectUnmarshaller
316 m_MinorVersion=nullptr;
318 m_IssueInstant=nullptr;
319 m_children.push_back(nullptr);
321 m_pos_Signature=m_children.begin();
324 RequestAbstractTypeImpl() {
328 virtual ~RequestAbstractTypeImpl() {
329 XMLString::release(&m_MinorVersion);
330 XMLString::release(&m_RequestID);
331 delete m_IssueInstant;
334 RequestAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
335 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
339 RequestAbstractTypeImpl(const RequestAbstractTypeImpl& src)
340 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
342 setMinorVersion(src.m_MinorVersion);
343 setRequestID(src.getRequestID());
344 setIssueInstant(src.getIssueInstant());
345 if (src.getSignature())
346 setSignature(src.getSignature()->cloneSignature());
347 VectorOf(RespondWith) v=getRespondWiths();
348 for (vector<RespondWith*>::const_iterator i=src.m_RespondWiths.begin(); i!=src.m_RespondWiths.end(); i++) {
350 v.push_back((*i)->cloneRespondWith());
355 //IMPL_TYPED_CHILD(Signature);
356 // Need customized setter.
358 Signature* m_Signature;
359 list<XMLObject*>::iterator m_pos_Signature;
361 Signature* getSignature() const {
365 void setSignature(Signature* sig) {
366 prepareForAssignment(m_Signature,sig);
367 *m_pos_Signature=m_Signature=sig;
368 // Sync content reference back up.
370 m_Signature->setContentReference(new opensaml::ContentReference(*this));
373 IMPL_INTEGER_ATTRIB(MinorVersion);
374 IMPL_STRING_ATTRIB(RequestID); // have to special-case getXMLID
375 const XMLCh* getXMLID() const {
376 pair<bool,int> v = getMinorVersion();
377 return (!v.first || v.second > 0) ? m_RequestID : nullptr;
379 const XMLCh* getID() const {
380 return getRequestID();
382 void releaseDOM() const {
384 getDOM()->removeAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
385 AbstractDOMCachingXMLObject::releaseDOM();
387 IMPL_DATETIME_ATTRIB(IssueInstant,0);
388 IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature);
391 void prepareForMarshalling() const {
393 declareNonVisibleNamespaces();
396 void marshallAttributes(DOMElement* domElement) const {
397 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
398 domElement->setAttributeNS(nullptr,MAJORVERSION,XML_ONE);
400 const_cast<RequestAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
401 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
403 const_cast<RequestAbstractTypeImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
404 domElement->setAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, m_RequestID);
405 if (*m_MinorVersion!=chDigit_0) {
406 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
407 domElement->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, true);
409 domElement->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
412 if (!m_IssueInstant) {
413 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(nullptr);
414 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
416 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
419 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
420 PROC_TYPED_CHILDREN(RespondWith,SAML1P_NS,false);
421 PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
422 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
425 void unmarshallAttributes(const DOMElement* domElement) {
426 // Standard processing, but then we check IDness.
427 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
428 if (m_RequestID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0)) {
429 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
430 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, true);
432 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
437 void processAttribute(const DOMAttr* attribute) {
438 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
439 if (XMLHelper::isNodeNamed(attribute,nullptr,MAJORVERSION)) {
440 if (!XMLString::equals(attribute->getValue(),XML_ONE))
441 throw UnmarshallingException("Request has invalid major version.");
443 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
444 PROC_STRING_ATTRIB(RequestID,REQUESTID,nullptr);
445 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
449 class SAML_DLLLOCAL RequestImpl : public virtual Request, public RequestAbstractTypeImpl
452 m_children.push_back(nullptr);
454 m_pos_Query=m_pos_Signature;
458 virtual ~RequestImpl() {}
460 RequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
461 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
465 RequestImpl(const RequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
468 setQuery(src.getQuery()->cloneQuery());
469 VectorOf(AssertionIDReference) v=getAssertionIDReferences();
470 for (vector<AssertionIDReference*>::const_iterator i=src.m_AssertionIDReferences.begin(); i!=src.m_AssertionIDReferences.end(); i++) {
472 v.push_back((*i)->cloneAssertionIDReference());
475 VectorOf(AssertionArtifact) v2=getAssertionArtifacts();
476 for (vector<AssertionArtifact*>::const_iterator i=src.m_AssertionArtifacts.begin(); i!=src.m_AssertionArtifacts.end(); i++) {
478 v2.push_back((*i)->cloneAssertionArtifact());
483 IMPL_XMLOBJECT_CLONE(Request);
484 RequestAbstractType* cloneRequestAbstractType() const {
485 return cloneRequest();
487 IMPL_TYPED_CHILD(Query);
489 SubjectQuery* getSubjectQuery() const {
490 return dynamic_cast<SubjectQuery*>(getQuery());
492 AuthenticationQuery* getAuthenticationQuery() const {
493 return dynamic_cast<AuthenticationQuery*>(getQuery());
495 AttributeQuery* getAttributeQuery() const {
496 return dynamic_cast<AttributeQuery*>(getQuery());
498 AuthorizationDecisionQuery* getAuthorizationDecisionQuery() const {
499 return dynamic_cast<AuthorizationDecisionQuery*>(getQuery());
502 void setSubjectQuery(SubjectQuery* q) {
505 void setAuthenticationQuery(AuthenticationQuery* q) {
508 void setAttributeQuery(AttributeQuery* q) {
511 void setAuthorizationDecisionQuery(AuthorizationDecisionQuery* q) {
515 IMPL_TYPED_CHILDREN(AssertionIDReference, m_children.end());
516 IMPL_TYPED_CHILDREN(AssertionArtifact, m_children.end());
519 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
520 PROC_TYPED_CHILD(Query,SAML1P_NS,true);
521 PROC_TYPED_CHILDREN(AssertionIDReference,SAML1_NS,false);
522 PROC_TYPED_CHILDREN(AssertionArtifact,SAML1P_NS,false);
523 RequestAbstractTypeImpl::processChildElement(childXMLObject,root);
527 class SAML_DLLLOCAL StatusCodeImpl : public virtual StatusCode,
528 public AbstractComplexElement,
529 public AbstractDOMCachingXMLObject,
530 public AbstractXMLObjectMarshaller,
531 public AbstractXMLObjectUnmarshaller
535 m_children.push_back(nullptr);
536 m_StatusCode=nullptr;
537 m_pos_StatusCode=m_children.begin();
540 virtual ~StatusCodeImpl() {
544 StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
545 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
549 StatusCodeImpl(const StatusCodeImpl& src)
550 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
552 setValue(src.getValue());
553 if (src.getStatusCode())
554 setStatusCode(src.getStatusCode()->cloneStatusCode());
557 IMPL_XMLOBJECT_CLONE(StatusCode);
558 IMPL_XMLOBJECT_ATTRIB(Value,xmltooling::QName);
559 IMPL_TYPED_CHILD(StatusCode);
562 void marshallAttributes(DOMElement* domElement) const {
563 MARSHALL_QNAME_ATTRIB(Value,VALUE,nullptr);
566 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
567 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,true);
568 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
571 void processAttribute(const DOMAttr* attribute) {
572 PROC_QNAME_ATTRIB(Value,VALUE,nullptr);
576 class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail,
577 public AbstractComplexElement,
578 public AbstractDOMCachingXMLObject,
579 public AbstractXMLObjectMarshaller,
580 public AbstractXMLObjectUnmarshaller
583 virtual ~StatusDetailImpl() {}
585 StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
586 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
589 StatusDetailImpl(const StatusDetailImpl& src)
590 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
591 VectorOf(XMLObject) v=getUnknownXMLObjects();
592 for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
593 v.push_back((*i)->clone());
596 IMPL_XMLOBJECT_CLONE(StatusDetail);
597 IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
600 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
601 getUnknownXMLObjects().push_back(childXMLObject);
605 class SAML_DLLLOCAL StatusImpl : public virtual Status,
606 public AbstractComplexElement,
607 public AbstractDOMCachingXMLObject,
608 public AbstractXMLObjectMarshaller,
609 public AbstractXMLObjectUnmarshaller
612 m_children.push_back(nullptr);
613 m_children.push_back(nullptr);
614 m_children.push_back(nullptr);
615 m_StatusCode=nullptr;
616 m_pos_StatusCode=m_children.begin();
617 m_StatusMessage=nullptr;
618 m_pos_StatusMessage=m_pos_StatusCode;
619 ++m_pos_StatusMessage;
620 m_StatusDetail=nullptr;
621 m_pos_StatusDetail=m_pos_StatusMessage;
622 ++m_pos_StatusDetail;
625 virtual ~StatusImpl() {}
627 StatusImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
628 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
632 StatusImpl(const StatusImpl& src)
633 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
635 if (src.getStatusCode())
636 setStatusCode(src.getStatusCode()->cloneStatusCode());
637 if (src.getStatusMessage())
638 setStatusMessage(src.getStatusMessage()->cloneStatusMessage());
639 if (src.getStatusDetail())
640 setStatusDetail(src.getStatusDetail()->cloneStatusDetail());
643 IMPL_XMLOBJECT_CLONE(Status);
644 IMPL_TYPED_CHILD(StatusCode);
645 IMPL_TYPED_CHILD(StatusMessage);
646 IMPL_TYPED_CHILD(StatusDetail);
649 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
650 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,false);
651 PROC_TYPED_CHILD(StatusMessage,SAML1P_NS,false);
652 PROC_TYPED_CHILD(StatusDetail,SAML1P_NS,false);
653 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
657 class SAML_DLLLOCAL ResponseAbstractTypeImpl : public virtual ResponseAbstractType,
658 public AbstractComplexElement,
659 public AbstractDOMCachingXMLObject,
660 public AbstractXMLObjectMarshaller,
661 public AbstractXMLObjectUnmarshaller
664 m_MinorVersion=nullptr;
665 m_ResponseID=nullptr;
666 m_InResponseTo=nullptr;
667 m_IssueInstant=nullptr;
669 m_children.push_back(nullptr);
671 m_pos_Signature=m_children.begin();
674 ResponseAbstractTypeImpl() {
678 virtual ~ResponseAbstractTypeImpl() {
679 XMLString::release(&m_MinorVersion);
680 XMLString::release(&m_ResponseID);
681 XMLString::release(&m_InResponseTo);
682 XMLString::release(&m_Recipient);
683 delete m_IssueInstant;
686 ResponseAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
687 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
691 ResponseAbstractTypeImpl(const ResponseAbstractTypeImpl& src)
692 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
694 setMinorVersion(src.m_MinorVersion);
695 setResponseID(src.getResponseID());
696 setInResponseTo(src.getInResponseTo());
697 setIssueInstant(src.getIssueInstant());
698 setRecipient(src.getRecipient());
699 if (src.getSignature())
700 setSignature(src.getSignature()->cloneSignature());
703 //IMPL_TYPED_CHILD(Signature);
704 // Need customized setter.
706 Signature* m_Signature;
707 list<XMLObject*>::iterator m_pos_Signature;
709 Signature* getSignature() const {
713 void setSignature(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 IMPL_INTEGER_ATTRIB(MinorVersion);
722 IMPL_STRING_ATTRIB(ResponseID); // have to special-case getXMLID
723 const XMLCh* getXMLID() const {
724 pair<bool,int> v = getMinorVersion();
725 return (!v.first || v.second > 0) ? m_ResponseID : nullptr;
727 const XMLCh* getID() const {
728 return getResponseID();
730 void releaseDOM() const {
732 getDOM()->removeAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
733 AbstractDOMCachingXMLObject::releaseDOM();
735 IMPL_STRING_ATTRIB(InResponseTo);
736 IMPL_DATETIME_ATTRIB(IssueInstant,0);
737 IMPL_STRING_ATTRIB(Recipient);
740 void prepareForMarshalling() const {
742 declareNonVisibleNamespaces();
745 void marshallAttributes(DOMElement* domElement) const {
746 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
747 domElement->setAttributeNS(nullptr,MAJORVERSION,XML_ONE);
749 const_cast<ResponseAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
750 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
752 const_cast<ResponseAbstractTypeImpl*>(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier();
753 domElement->setAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, m_ResponseID);
754 if (*m_MinorVersion!=chDigit_0) {
755 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
756 domElement->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, true);
758 domElement->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
761 MARSHALL_STRING_ATTRIB(InResponseTo,INRESPONSETO,nullptr);
762 if (!m_IssueInstant) {
763 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(nullptr);
764 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
766 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
767 MARSHALL_STRING_ATTRIB(Recipient,RECIPIENT,nullptr);
770 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
771 PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
772 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
775 void unmarshallAttributes(const DOMElement* domElement) {
776 // Standard processing, but then we check IDness.
777 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
778 if (m_ResponseID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0)) {
779 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
780 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, true);
782 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
787 void processAttribute(const DOMAttr* attribute) {
788 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
789 if (XMLHelper::isNodeNamed(attribute,nullptr,MAJORVERSION)) {
790 if (!XMLString::equals(attribute->getValue(),XML_ONE))
791 throw UnmarshallingException("Response has invalid major version.");
793 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
794 PROC_STRING_ATTRIB(ResponseID,RESPONSEID,nullptr);
795 PROC_STRING_ATTRIB(InResponseTo,INRESPONSETO,nullptr);
796 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
797 PROC_STRING_ATTRIB(Recipient,RECIPIENT,nullptr);
801 class SAML_DLLLOCAL ResponseImpl : public virtual Response, public ResponseAbstractTypeImpl
804 m_children.push_back(nullptr);
806 m_pos_Status=m_pos_Signature;
810 virtual ~ResponseImpl() {}
812 ResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
813 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
817 ResponseImpl(const ResponseImpl& src) : AbstractXMLObject(src), ResponseAbstractTypeImpl(src) {
820 setStatus(src.getStatus()->cloneStatus());
821 VectorOf(saml1::Assertion) v=getAssertions();
822 for (vector<saml1::Assertion*>::const_iterator i=src.m_Assertions.begin(); i!=src.m_Assertions.end(); i++) {
824 v.push_back((*i)->cloneAssertion());
829 IMPL_XMLOBJECT_CLONE(Response);
830 ResponseAbstractType* cloneResponseAbstractType() const {
831 return cloneResponse();
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);