2 * Copyright 2001-2009 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/XMLHelper.h>
38 #include <xercesc/util/XMLUniDefs.hpp>
40 using namespace opensaml::saml1p;
41 using namespace opensaml::saml1;
42 using namespace xmlsignature;
43 using namespace xmltooling;
45 using xmlconstants::XMLSIG_NS;
46 using xmlconstants::XML_ONE;
47 using samlconstants::SAML1P_NS;
48 using samlconstants::SAML1_NS;
49 using samlconstants::SAML1P_PREFIX;
51 #if defined (_MSC_VER)
52 #pragma warning( push )
53 #pragma warning( disable : 4250 4251 )
59 DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,AssertionArtifact);
60 DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,StatusMessage);
62 class SAML_DLLLOCAL RespondWithImpl : public virtual RespondWith,
63 public AbstractSimpleElement,
64 public AbstractDOMCachingXMLObject,
65 public AbstractXMLObjectMarshaller,
66 public AbstractXMLObjectUnmarshaller
68 xmltooling::QName* m_qname;
70 virtual ~RespondWithImpl() {
74 RespondWithImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
75 : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_qname(NULL) {
78 RespondWithImpl(const RespondWithImpl& src)
79 : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src), m_qname(NULL) {
80 setQName(src.getQName());
83 xmltooling::QName* getQName() const {
87 void setQName(const xmltooling::QName* qname) {
88 m_qname=prepareForAssignment(m_qname,qname);
90 auto_ptr_XMLCh temp(m_qname->toString().c_str());
91 setTextContent(temp.get());
97 IMPL_XMLOBJECT_CLONE(RespondWith);
100 class SAML_DLLLOCAL QueryImpl : public virtual Query, public AnyElementImpl
103 virtual ~QueryImpl() {}
105 QueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
106 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
109 QueryImpl(const QueryImpl& src) : AbstractXMLObject(src), AnyElementImpl(src) {}
111 IMPL_XMLOBJECT_CLONE(Query);
114 class SAML_DLLLOCAL SubjectQueryImpl : public virtual SubjectQuery,
115 public AbstractComplexElement,
116 public AbstractDOMCachingXMLObject,
117 public AbstractXMLObjectMarshaller,
118 public AbstractXMLObjectUnmarshaller
122 m_children.push_back(NULL);
123 m_pos_Subject=m_children.begin();
130 virtual ~SubjectQueryImpl() {}
132 SubjectQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
133 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
137 SubjectQueryImpl(const SubjectQueryImpl& src)
138 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
140 if (src.getSubject())
141 setSubject(src.getSubject()->cloneSubject());
144 IMPL_TYPED_CHILD(Subject);
147 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
148 PROC_TYPED_CHILD(Subject,SAML1_NS,true);
149 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
153 class SAML_DLLLOCAL AuthenticationQueryImpl : public virtual AuthenticationQuery, public SubjectQueryImpl
156 m_AuthenticationMethod=NULL;
159 virtual ~AuthenticationQueryImpl() {
160 XMLString::release(&m_AuthenticationMethod);
163 AuthenticationQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
164 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
168 AuthenticationQueryImpl(const AuthenticationQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
170 setAuthenticationMethod(src.getAuthenticationMethod());
173 IMPL_XMLOBJECT_CLONE(AuthenticationQuery);
174 SubjectQuery* cloneSubjectQuery() const {
175 return cloneAuthenticationQuery();
177 Query* cloneQuery() const {
178 return cloneAuthenticationQuery();
180 IMPL_STRING_ATTRIB(AuthenticationMethod);
183 void marshallAttributes(DOMElement* domElement) const {
184 MARSHALL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL);
185 SubjectQueryImpl::marshallAttributes(domElement);
188 void processAttribute(const DOMAttr* attribute) {
189 PROC_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL);
190 SubjectQueryImpl::processAttribute(attribute);
194 class SAML_DLLLOCAL AttributeQueryImpl : public virtual AttributeQuery, public SubjectQueryImpl
200 virtual ~AttributeQueryImpl() {
201 XMLString::release(&m_Resource);
204 AttributeQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
205 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
209 AttributeQueryImpl(const AttributeQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
211 setResource(src.getResource());
212 VectorOf(AttributeDesignator) v=getAttributeDesignators();
213 for (vector<AttributeDesignator*>::const_iterator i=src.m_AttributeDesignators.begin(); i!=src.m_AttributeDesignators.end(); i++) {
215 v.push_back((*i)->cloneAttributeDesignator());
220 IMPL_XMLOBJECT_CLONE(AttributeQuery);
221 SubjectQuery* cloneSubjectQuery() const {
222 return cloneAttributeQuery();
224 Query* cloneQuery() const {
225 return cloneAttributeQuery();
227 IMPL_STRING_ATTRIB(Resource);
228 IMPL_TYPED_CHILDREN(AttributeDesignator,m_children.end());
231 void marshallAttributes(DOMElement* domElement) const {
232 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,NULL);
233 SubjectQueryImpl::marshallAttributes(domElement);
236 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
237 PROC_TYPED_CHILDREN(AttributeDesignator,SAML1_NS,true);
238 SubjectQueryImpl::processChildElement(childXMLObject,root);
241 void processAttribute(const DOMAttr* attribute) {
242 PROC_STRING_ATTRIB(Resource,RESOURCE,NULL);
243 SubjectQueryImpl::processAttribute(attribute);
247 class SAML_DLLLOCAL AuthorizationDecisionQueryImpl : public virtual AuthorizationDecisionQuery, public SubjectQueryImpl
252 m_children.push_back(NULL);
253 m_pos_Evidence=m_pos_Subject;
257 virtual ~AuthorizationDecisionQueryImpl() {
258 XMLString::release(&m_Resource);
261 AuthorizationDecisionQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
262 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
266 AuthorizationDecisionQueryImpl(const AuthorizationDecisionQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
268 setResource(src.getResource());
269 if (src.getEvidence())
270 setEvidence(src.getEvidence()->cloneEvidence());
271 VectorOf(Action) v=getActions();
272 for (vector<Action*>::const_iterator i=src.m_Actions.begin(); i!=src.m_Actions.end(); i++) {
274 v.push_back((*i)->cloneAction());
279 IMPL_XMLOBJECT_CLONE(AuthorizationDecisionQuery);
280 SubjectQuery* cloneSubjectQuery() const {
281 return cloneAuthorizationDecisionQuery();
283 Query* cloneQuery() const {
284 return cloneAuthorizationDecisionQuery();
286 IMPL_STRING_ATTRIB(Resource);
287 IMPL_TYPED_CHILD(Evidence);
288 IMPL_TYPED_CHILDREN(Action, m_pos_Evidence);
291 void marshallAttributes(DOMElement* domElement) const {
292 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,NULL);
293 SubjectQueryImpl::marshallAttributes(domElement);
296 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
297 PROC_TYPED_CHILD(Evidence,SAML1_NS,false);
298 PROC_TYPED_CHILDREN(Action,SAML1_NS,false);
299 SubjectQueryImpl::processChildElement(childXMLObject,root);
302 void processAttribute(const DOMAttr* attribute) {
303 PROC_STRING_ATTRIB(Resource,RESOURCE,NULL);
304 SubjectQueryImpl::processAttribute(attribute);
308 class SAML_DLLLOCAL RequestAbstractTypeImpl : public virtual RequestAbstractType,
309 public AbstractComplexElement,
310 public AbstractDOMCachingXMLObject,
311 public AbstractXMLObjectMarshaller,
312 public AbstractXMLObjectUnmarshaller
318 m_children.push_back(NULL);
320 m_pos_Signature=m_children.begin();
323 RequestAbstractTypeImpl() {
327 virtual ~RequestAbstractTypeImpl() {
328 XMLString::release(&m_MinorVersion);
329 XMLString::release(&m_RequestID);
330 delete m_IssueInstant;
333 RequestAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
334 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
338 RequestAbstractTypeImpl(const RequestAbstractTypeImpl& src)
339 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
341 setMinorVersion(src.m_MinorVersion);
342 setRequestID(src.getRequestID());
343 setIssueInstant(src.getIssueInstant());
344 if (src.getSignature())
345 setSignature(src.getSignature()->cloneSignature());
346 VectorOf(RespondWith) v=getRespondWiths();
347 for (vector<RespondWith*>::const_iterator i=src.m_RespondWiths.begin(); i!=src.m_RespondWiths.end(); i++) {
349 v.push_back((*i)->cloneRespondWith());
354 //IMPL_TYPED_CHILD(Signature);
355 // Need customized setter.
357 Signature* m_Signature;
358 list<XMLObject*>::iterator m_pos_Signature;
360 Signature* getSignature() const {
364 void setSignature(Signature* sig) {
365 prepareForAssignment(m_Signature,sig);
366 *m_pos_Signature=m_Signature=sig;
367 // Sync content reference back up.
369 m_Signature->setContentReference(new opensaml::ContentReference(*this));
372 IMPL_INTEGER_ATTRIB(MinorVersion);
373 IMPL_STRING_ATTRIB(RequestID); // have to special-case getXMLID
374 const XMLCh* getXMLID() const {
375 pair<bool,int> v = getMinorVersion();
376 return (!v.first || v.second > 0) ? m_RequestID : NULL;
378 const XMLCh* getID() const {
379 return getRequestID();
381 IMPL_DATETIME_ATTRIB(IssueInstant,0);
382 IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature);
385 void marshallAttributes(DOMElement* domElement) const {
386 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
387 domElement->setAttributeNS(NULL,MAJORVERSION,XML_ONE);
389 const_cast<RequestAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
390 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
392 const_cast<RequestAbstractTypeImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
393 domElement->setAttributeNS(NULL, REQUESTID_ATTRIB_NAME, m_RequestID);
394 if (*m_MinorVersion!=chDigit_0) {
395 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
396 domElement->setIdAttributeNS(NULL, REQUESTID_ATTRIB_NAME, true);
398 domElement->setIdAttributeNS(NULL, REQUESTID_ATTRIB_NAME);
401 if (!m_IssueInstant) {
402 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(NULL);
403 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
405 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
408 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
409 PROC_TYPED_CHILDREN(RespondWith,SAML1P_NS,false);
410 PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
411 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
414 void unmarshallAttributes(const DOMElement* domElement) {
415 // Standard processing, but then we check IDness.
416 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
417 if (m_RequestID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0)) {
418 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
419 const_cast<DOMElement*>(domElement)->setIdAttributeNS(NULL, REQUESTID_ATTRIB_NAME, true);
421 const_cast<DOMElement*>(domElement)->setIdAttributeNS(NULL, REQUESTID_ATTRIB_NAME);
426 void processAttribute(const DOMAttr* attribute) {
427 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
428 if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) {
429 if (!XMLString::equals(attribute->getValue(),XML_ONE))
430 throw UnmarshallingException("Request has invalid major version.");
432 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
433 PROC_STRING_ATTRIB(RequestID,REQUESTID,NULL);
434 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
438 class SAML_DLLLOCAL RequestImpl : public virtual Request, public RequestAbstractTypeImpl
441 m_children.push_back(NULL);
443 m_pos_Query=m_pos_Signature;
447 virtual ~RequestImpl() {}
449 RequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
450 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
454 RequestImpl(const RequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
457 setQuery(src.getQuery()->cloneQuery());
458 VectorOf(AssertionIDReference) v=getAssertionIDReferences();
459 for (vector<AssertionIDReference*>::const_iterator i=src.m_AssertionIDReferences.begin(); i!=src.m_AssertionIDReferences.end(); i++) {
461 v.push_back((*i)->cloneAssertionIDReference());
464 VectorOf(AssertionArtifact) v2=getAssertionArtifacts();
465 for (vector<AssertionArtifact*>::const_iterator i=src.m_AssertionArtifacts.begin(); i!=src.m_AssertionArtifacts.end(); i++) {
467 v2.push_back((*i)->cloneAssertionArtifact());
472 IMPL_XMLOBJECT_CLONE(Request);
473 RequestAbstractType* cloneRequestAbstractType() const {
474 return cloneRequest();
476 IMPL_TYPED_CHILD(Query);
478 SubjectQuery* getSubjectQuery() const {
479 return dynamic_cast<SubjectQuery*>(getQuery());
481 AuthenticationQuery* getAuthenticationQuery() const {
482 return dynamic_cast<AuthenticationQuery*>(getQuery());
484 AttributeQuery* getAttributeQuery() const {
485 return dynamic_cast<AttributeQuery*>(getQuery());
487 AuthorizationDecisionQuery* getAuthorizationDecisionQuery() const {
488 return dynamic_cast<AuthorizationDecisionQuery*>(getQuery());
491 void setSubjectQuery(SubjectQuery* q) {
494 void setAuthenticationQuery(AuthenticationQuery* q) {
497 void setAttributeQuery(AttributeQuery* q) {
500 void setAuthorizationDecisionQuery(AuthorizationDecisionQuery* q) {
504 IMPL_TYPED_CHILDREN(AssertionIDReference, m_children.end());
505 IMPL_TYPED_CHILDREN(AssertionArtifact, m_children.end());
508 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
509 PROC_TYPED_CHILD(Query,SAML1P_NS,true);
510 PROC_TYPED_CHILDREN(AssertionIDReference,SAML1_NS,false);
511 PROC_TYPED_CHILDREN(AssertionArtifact,SAML1P_NS,false);
512 RequestAbstractTypeImpl::processChildElement(childXMLObject,root);
516 class SAML_DLLLOCAL StatusCodeImpl : public virtual StatusCode,
517 public AbstractComplexElement,
518 public AbstractDOMCachingXMLObject,
519 public AbstractXMLObjectMarshaller,
520 public AbstractXMLObjectUnmarshaller
524 m_children.push_back(NULL);
526 m_pos_StatusCode=m_children.begin();
529 virtual ~StatusCodeImpl() {
533 StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
534 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
538 StatusCodeImpl(const StatusCodeImpl& src)
539 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
541 setValue(src.getValue());
542 if (src.getStatusCode())
543 setStatusCode(src.getStatusCode()->cloneStatusCode());
546 IMPL_XMLOBJECT_CLONE(StatusCode);
547 IMPL_XMLOBJECT_ATTRIB(Value,xmltooling::QName);
548 IMPL_TYPED_CHILD(StatusCode);
551 void marshallAttributes(DOMElement* domElement) const {
552 MARSHALL_QNAME_ATTRIB(Value,VALUE,NULL);
555 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
556 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,true);
557 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
560 void processAttribute(const DOMAttr* attribute) {
561 PROC_QNAME_ATTRIB(Value,VALUE,NULL);
565 class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail,
566 public AbstractComplexElement,
567 public AbstractDOMCachingXMLObject,
568 public AbstractXMLObjectMarshaller,
569 public AbstractXMLObjectUnmarshaller
572 virtual ~StatusDetailImpl() {}
574 StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
575 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
578 StatusDetailImpl(const StatusDetailImpl& src)
579 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
580 VectorOf(XMLObject) v=getUnknownXMLObjects();
581 for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
582 v.push_back((*i)->clone());
585 IMPL_XMLOBJECT_CLONE(StatusDetail);
586 IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
589 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
590 getUnknownXMLObjects().push_back(childXMLObject);
594 class SAML_DLLLOCAL StatusImpl : public virtual Status,
595 public AbstractComplexElement,
596 public AbstractDOMCachingXMLObject,
597 public AbstractXMLObjectMarshaller,
598 public AbstractXMLObjectUnmarshaller
601 m_children.push_back(NULL);
602 m_children.push_back(NULL);
603 m_children.push_back(NULL);
605 m_pos_StatusCode=m_children.begin();
606 m_StatusMessage=NULL;
607 m_pos_StatusMessage=m_pos_StatusCode;
608 ++m_pos_StatusMessage;
610 m_pos_StatusDetail=m_pos_StatusMessage;
611 ++m_pos_StatusDetail;
614 virtual ~StatusImpl() {}
616 StatusImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
617 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
621 StatusImpl(const StatusImpl& src)
622 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
624 if (src.getStatusCode())
625 setStatusCode(src.getStatusCode()->cloneStatusCode());
626 if (src.getStatusMessage())
627 setStatusMessage(src.getStatusMessage()->cloneStatusMessage());
628 if (src.getStatusDetail())
629 setStatusDetail(src.getStatusDetail()->cloneStatusDetail());
632 IMPL_XMLOBJECT_CLONE(Status);
633 IMPL_TYPED_CHILD(StatusCode);
634 IMPL_TYPED_CHILD(StatusMessage);
635 IMPL_TYPED_CHILD(StatusDetail);
638 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
639 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,false);
640 PROC_TYPED_CHILD(StatusMessage,SAML1P_NS,false);
641 PROC_TYPED_CHILD(StatusDetail,SAML1P_NS,false);
642 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
646 class SAML_DLLLOCAL ResponseAbstractTypeImpl : public virtual ResponseAbstractType,
647 public AbstractComplexElement,
648 public AbstractDOMCachingXMLObject,
649 public AbstractXMLObjectMarshaller,
650 public AbstractXMLObjectUnmarshaller
658 m_children.push_back(NULL);
660 m_pos_Signature=m_children.begin();
663 ResponseAbstractTypeImpl() {
667 virtual ~ResponseAbstractTypeImpl() {
668 XMLString::release(&m_MinorVersion);
669 XMLString::release(&m_ResponseID);
670 XMLString::release(&m_InResponseTo);
671 XMLString::release(&m_Recipient);
672 delete m_IssueInstant;
675 ResponseAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
676 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
680 ResponseAbstractTypeImpl(const ResponseAbstractTypeImpl& src)
681 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
683 setMinorVersion(src.m_MinorVersion);
684 setResponseID(src.getResponseID());
685 setInResponseTo(src.getInResponseTo());
686 setIssueInstant(src.getIssueInstant());
687 setRecipient(src.getRecipient());
688 if (src.getSignature())
689 setSignature(src.getSignature()->cloneSignature());
692 //IMPL_TYPED_CHILD(Signature);
693 // Need customized setter.
695 Signature* m_Signature;
696 list<XMLObject*>::iterator m_pos_Signature;
698 Signature* getSignature() const {
702 void setSignature(Signature* sig) {
703 prepareForAssignment(m_Signature,sig);
704 *m_pos_Signature=m_Signature=sig;
705 // Sync content reference back up.
707 m_Signature->setContentReference(new opensaml::ContentReference(*this));
710 IMPL_INTEGER_ATTRIB(MinorVersion);
711 IMPL_STRING_ATTRIB(ResponseID); // have to special-case getXMLID
712 const XMLCh* getXMLID() const {
713 pair<bool,int> v = getMinorVersion();
714 return (!v.first || v.second > 0) ? m_ResponseID : NULL;
716 const XMLCh* getID() const {
717 return getResponseID();
719 IMPL_STRING_ATTRIB(InResponseTo);
720 IMPL_DATETIME_ATTRIB(IssueInstant,0);
721 IMPL_STRING_ATTRIB(Recipient);
724 void marshallAttributes(DOMElement* domElement) const {
725 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
726 domElement->setAttributeNS(NULL,MAJORVERSION,XML_ONE);
728 const_cast<ResponseAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
729 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
731 const_cast<ResponseAbstractTypeImpl*>(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier();
732 domElement->setAttributeNS(NULL, RESPONSEID_ATTRIB_NAME, m_ResponseID);
733 if (*m_MinorVersion!=chDigit_0) {
734 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
735 domElement->setIdAttributeNS(NULL, RESPONSEID_ATTRIB_NAME, true);
737 domElement->setIdAttributeNS(NULL, RESPONSEID_ATTRIB_NAME);
740 MARSHALL_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL);
741 if (!m_IssueInstant) {
742 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(NULL);
743 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
745 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
746 MARSHALL_STRING_ATTRIB(Recipient,RECIPIENT,NULL);
749 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
750 PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
751 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
754 void unmarshallAttributes(const DOMElement* domElement) {
755 // Standard processing, but then we check IDness.
756 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
757 if (m_ResponseID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0)) {
758 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
759 const_cast<DOMElement*>(domElement)->setIdAttributeNS(NULL, RESPONSEID_ATTRIB_NAME, true);
761 const_cast<DOMElement*>(domElement)->setIdAttributeNS(NULL, RESPONSEID_ATTRIB_NAME);
766 void processAttribute(const DOMAttr* attribute) {
767 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
768 if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) {
769 if (!XMLString::equals(attribute->getValue(),XML_ONE))
770 throw UnmarshallingException("Response has invalid major version.");
772 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
773 PROC_STRING_ATTRIB(ResponseID,RESPONSEID,NULL);
774 PROC_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL);
775 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
776 PROC_STRING_ATTRIB(Recipient,RECIPIENT,NULL);
780 class SAML_DLLLOCAL ResponseImpl : public virtual Response, public ResponseAbstractTypeImpl
783 m_children.push_back(NULL);
785 m_pos_Status=m_pos_Signature;
789 virtual ~ResponseImpl() {}
791 ResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
792 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
796 ResponseImpl(const ResponseImpl& src) : AbstractXMLObject(src), ResponseAbstractTypeImpl(src) {
799 setStatus(src.getStatus()->cloneStatus());
800 VectorOf(saml1::Assertion) v=getAssertions();
801 for (vector<saml1::Assertion*>::const_iterator i=src.m_Assertions.begin(); i!=src.m_Assertions.end(); i++) {
803 v.push_back((*i)->cloneAssertion());
808 IMPL_XMLOBJECT_CLONE(Response);
809 ResponseAbstractType* cloneResponseAbstractType() const {
810 return cloneResponse();
812 IMPL_TYPED_CHILD(Status);
813 IMPL_TYPED_FOREIGN_CHILDREN(Assertion,saml1,m_children.end());
816 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
817 PROC_TYPED_CHILD(Status,SAML1P_NS,false);
818 PROC_TYPED_FOREIGN_CHILDREN(Assertion,saml1,SAML1_NS,true);
819 ResponseAbstractTypeImpl::processChildElement(childXMLObject,root);
826 #if defined (_MSC_VER)
827 #pragma warning( pop )
830 // Builder Implementations
832 IMPL_XMLOBJECTBUILDER(AssertionArtifact);
833 IMPL_XMLOBJECTBUILDER(AttributeQuery);
834 IMPL_XMLOBJECTBUILDER(AuthenticationQuery);
835 IMPL_XMLOBJECTBUILDER(AuthorizationDecisionQuery);
836 IMPL_XMLOBJECTBUILDER(Query);
837 IMPL_XMLOBJECTBUILDER(Request);
838 IMPL_XMLOBJECTBUILDER(RespondWith);
839 IMPL_XMLOBJECTBUILDER(Response);
840 IMPL_XMLOBJECTBUILDER(Status);
841 IMPL_XMLOBJECTBUILDER(StatusCode);
842 IMPL_XMLOBJECTBUILDER(StatusDetail);
843 IMPL_XMLOBJECTBUILDER(StatusMessage);
846 const XMLCh RequestAbstractType::LOCAL_NAME[] = {chNull};
847 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);
848 const XMLCh RequestAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
849 const XMLCh RequestAbstractType::REQUESTID_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,I,D);
850 const XMLCh RequestAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
851 const XMLCh ResponseAbstractType::LOCAL_NAME[] = {chNull};
852 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);
853 const XMLCh ResponseAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
854 const XMLCh ResponseAbstractType::RESPONSEID_ATTRIB_NAME[] = UNICODE_LITERAL_10(R,e,s,p,o,n,s,e,I,D);
855 const XMLCh ResponseAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
856 const XMLCh ResponseAbstractType::INRESPONSETO_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,n,R,e,s,p,o,n,s,e,T,o);
857 const XMLCh ResponseAbstractType::RECIPIENT_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,c,i,p,i,e,n,t);
858 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);
859 const XMLCh AttributeQuery::LOCAL_NAME[] = UNICODE_LITERAL_14(A,t,t,r,i,b,u,t,e,Q,u,e,r,y);
860 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);
861 const XMLCh AttributeQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
862 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);
863 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);
864 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);
865 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);
866 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);
867 const XMLCh AuthorizationDecisionQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
868 const XMLCh Query::LOCAL_NAME[] = UNICODE_LITERAL_5(Q,u,e,r,y);
869 const XMLCh Request::LOCAL_NAME[] = UNICODE_LITERAL_7(R,e,q,u,e,s,t);
870 const XMLCh Request::TYPE_NAME[] = UNICODE_LITERAL_11(R,e,q,u,e,s,t,T,y,p,e);
871 const XMLCh RespondWith::LOCAL_NAME[] = UNICODE_LITERAL_11(R,e,s,p,o,n,d,W,i,t,h);
872 const XMLCh Response::LOCAL_NAME[] = UNICODE_LITERAL_8(R,e,s,p,o,n,s,e);
873 const XMLCh Response::TYPE_NAME[] = UNICODE_LITERAL_12(R,e,s,p,o,n,s,e,T,y,p,e);
874 const XMLCh Status::LOCAL_NAME[] = UNICODE_LITERAL_6(S,t,a,t,u,s);
875 const XMLCh Status::TYPE_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,T,y,p,e);
876 const XMLCh StatusCode::LOCAL_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,C,o,d,e);
877 const XMLCh StatusCode::TYPE_NAME[] = UNICODE_LITERAL_14(S,t,a,t,u,s,C,o,d,e,T,y,p,e);
878 const XMLCh StatusCode::VALUE_ATTRIB_NAME[] = UNICODE_LITERAL_5(V,a,l,u,e);
879 const XMLCh StatusDetail::LOCAL_NAME[] = UNICODE_LITERAL_12(S,t,a,t,u,s,D,e,t,a,i,l);
880 const XMLCh StatusDetail::TYPE_NAME[] = UNICODE_LITERAL_16(S,t,a,t,u,s,D,e,t,a,i,l,T,y,p,e);
881 const XMLCh StatusMessage::LOCAL_NAME[] = UNICODE_LITERAL_13(S,t,a,t,u,s,M,e,s,s,a,g,e);
882 const XMLCh SubjectQuery::LOCAL_NAME[] = UNICODE_LITERAL_12(S,u,b,j,e,c,t,Q,u,e,r,y);
884 #define XCH(ch) chLatin_##ch
885 #define XNUM(d) chDigit_##d
887 const XMLCh _SUCCESS[] = UNICODE_LITERAL_7(S,u,c,c,e,s,s);
888 const XMLCh _REQUESTER[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,e,r);
889 const XMLCh _RESPONDER[] = UNICODE_LITERAL_9(R,e,s,p,o,n,d,e,r);
890 const XMLCh _VERSIONMISMATCH[] = UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h);
892 xmltooling::QName StatusCode::SUCCESS(SAML1P_NS,_SUCCESS,SAML1P_PREFIX);
893 xmltooling::QName StatusCode::REQUESTER(SAML1P_NS,_REQUESTER,SAML1P_PREFIX);
894 xmltooling::QName StatusCode::RESPONDER(SAML1P_NS,_RESPONDER,SAML1P_PREFIX);
895 xmltooling::QName StatusCode::VERSIONMISMATCH(SAML1P_NS,_VERSIONMISMATCH,SAML1P_PREFIX);