2 * Copyright 2001-2007 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"
28 #include <xmltooling/AbstractComplexElement.h>
29 #include <xmltooling/AbstractSimpleElement.h>
30 #include <xmltooling/impl/AnyElement.h>
31 #include <xmltooling/io/AbstractXMLObjectMarshaller.h>
32 #include <xmltooling/io/AbstractXMLObjectUnmarshaller.h>
33 #include <xmltooling/util/XMLHelper.h>
36 #include <xercesc/util/XMLUniDefs.hpp>
38 using namespace opensaml::saml1p;
39 using namespace opensaml::saml1;
40 using namespace xmlsignature;
41 using namespace xmltooling;
43 using xmlconstants::XMLSIG_NS;
44 using xmlconstants::XML_ONE;
45 using samlconstants::SAML1P_NS;
46 using samlconstants::SAML1_NS;
47 using samlconstants::SAML1P_PREFIX;
49 #if defined (_MSC_VER)
50 #pragma warning( push )
51 #pragma warning( disable : 4250 4251 )
57 DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,AssertionArtifact);
58 DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,StatusMessage);
60 class SAML_DLLLOCAL RespondWithImpl : public virtual RespondWith,
61 public AbstractSimpleElement,
62 public AbstractDOMCachingXMLObject,
63 public AbstractXMLObjectMarshaller,
64 public AbstractXMLObjectUnmarshaller
68 virtual ~RespondWithImpl() {
72 RespondWithImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
73 : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_qname(NULL) {
76 RespondWithImpl(const RespondWithImpl& src)
77 : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src), m_qname(NULL) {
78 setQName(src.getQName());
81 QName* getQName() const {
85 void setQName(const QName* qname) {
86 m_qname=prepareForAssignment(m_qname,qname);
88 auto_ptr_XMLCh temp(m_qname->toString().c_str());
89 setTextContent(temp.get());
95 IMPL_XMLOBJECT_CLONE(RespondWith);
98 class SAML_DLLLOCAL SubjectQueryImpl : public virtual SubjectQuery,
99 public AbstractComplexElement,
100 public AbstractDOMCachingXMLObject,
101 public AbstractXMLObjectMarshaller,
102 public AbstractXMLObjectUnmarshaller
106 m_children.push_back(NULL);
107 m_pos_Subject=m_children.begin();
114 virtual ~SubjectQueryImpl() {}
116 SubjectQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
117 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
121 SubjectQueryImpl(const SubjectQueryImpl& src)
122 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
124 if (src.getSubject())
125 setSubject(src.getSubject()->cloneSubject());
128 IMPL_TYPED_CHILD(Subject);
131 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
132 PROC_TYPED_CHILD(Subject,SAML1_NS,true);
133 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
137 class SAML_DLLLOCAL AuthenticationQueryImpl : public virtual AuthenticationQuery, public SubjectQueryImpl
140 m_AuthenticationMethod=NULL;
143 virtual ~AuthenticationQueryImpl() {
144 XMLString::release(&m_AuthenticationMethod);
147 AuthenticationQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
148 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
152 AuthenticationQueryImpl(const AuthenticationQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
154 setAuthenticationMethod(src.getAuthenticationMethod());
157 IMPL_XMLOBJECT_CLONE(AuthenticationQuery);
158 SubjectQuery* cloneSubjectQuery() const {
159 return cloneAuthenticationQuery();
161 Query* cloneQuery() const {
162 return cloneAuthenticationQuery();
164 IMPL_STRING_ATTRIB(AuthenticationMethod);
167 void marshallAttributes(DOMElement* domElement) const {
168 MARSHALL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL);
169 SubjectQueryImpl::marshallAttributes(domElement);
172 void processAttribute(const DOMAttr* attribute) {
173 PROC_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL);
174 SubjectQueryImpl::processAttribute(attribute);
178 class SAML_DLLLOCAL AttributeQueryImpl : public virtual AttributeQuery, public SubjectQueryImpl
184 virtual ~AttributeQueryImpl() {
185 XMLString::release(&m_Resource);
188 AttributeQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
189 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
193 AttributeQueryImpl(const AttributeQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
195 setResource(src.getResource());
196 VectorOf(AttributeDesignator) v=getAttributeDesignators();
197 for (vector<AttributeDesignator*>::const_iterator i=src.m_AttributeDesignators.begin(); i!=src.m_AttributeDesignators.end(); i++) {
199 v.push_back((*i)->cloneAttributeDesignator());
204 IMPL_XMLOBJECT_CLONE(AttributeQuery);
205 SubjectQuery* cloneSubjectQuery() const {
206 return cloneAttributeQuery();
208 Query* cloneQuery() const {
209 return cloneAttributeQuery();
211 IMPL_STRING_ATTRIB(Resource);
212 IMPL_TYPED_CHILDREN(AttributeDesignator,m_children.end());
215 void marshallAttributes(DOMElement* domElement) const {
216 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,NULL);
217 SubjectQueryImpl::marshallAttributes(domElement);
220 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
221 PROC_TYPED_CHILDREN(AttributeDesignator,SAML1_NS,true);
222 SubjectQueryImpl::processChildElement(childXMLObject,root);
225 void processAttribute(const DOMAttr* attribute) {
226 PROC_STRING_ATTRIB(Resource,RESOURCE,NULL);
227 SubjectQueryImpl::processAttribute(attribute);
231 class SAML_DLLLOCAL AuthorizationDecisionQueryImpl : public virtual AuthorizationDecisionQuery, public SubjectQueryImpl
236 m_children.push_back(NULL);
237 m_pos_Evidence=m_pos_Subject;
241 virtual ~AuthorizationDecisionQueryImpl() {
242 XMLString::release(&m_Resource);
245 AuthorizationDecisionQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
246 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
250 AuthorizationDecisionQueryImpl(const AuthorizationDecisionQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
252 setResource(src.getResource());
253 if (src.getEvidence())
254 setEvidence(src.getEvidence()->cloneEvidence());
255 VectorOf(Action) v=getActions();
256 for (vector<Action*>::const_iterator i=src.m_Actions.begin(); i!=src.m_Actions.end(); i++) {
258 v.push_back((*i)->cloneAction());
263 IMPL_XMLOBJECT_CLONE(AuthorizationDecisionQuery);
264 SubjectQuery* cloneSubjectQuery() const {
265 return cloneAuthorizationDecisionQuery();
267 Query* cloneQuery() const {
268 return cloneAuthorizationDecisionQuery();
270 IMPL_STRING_ATTRIB(Resource);
271 IMPL_TYPED_CHILD(Evidence);
272 IMPL_TYPED_CHILDREN(Action, m_pos_Evidence);
275 void marshallAttributes(DOMElement* domElement) const {
276 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,NULL);
277 SubjectQueryImpl::marshallAttributes(domElement);
280 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
281 PROC_TYPED_CHILD(Evidence,SAML1_NS,false);
282 PROC_TYPED_CHILDREN(Action,SAML1_NS,false);
283 SubjectQueryImpl::processChildElement(childXMLObject,root);
286 void processAttribute(const DOMAttr* attribute) {
287 PROC_STRING_ATTRIB(Resource,RESOURCE,NULL);
288 SubjectQueryImpl::processAttribute(attribute);
292 class SAML_DLLLOCAL RequestAbstractTypeImpl : public virtual RequestAbstractType,
293 public AbstractComplexElement,
294 public AbstractDOMCachingXMLObject,
295 public AbstractXMLObjectMarshaller,
296 public AbstractXMLObjectUnmarshaller
302 m_children.push_back(NULL);
304 m_pos_Signature=m_children.begin();
307 RequestAbstractTypeImpl() {
311 virtual ~RequestAbstractTypeImpl() {
312 XMLString::release(&m_MinorVersion);
313 XMLString::release(&m_RequestID);
314 delete m_IssueInstant;
317 RequestAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
318 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
322 RequestAbstractTypeImpl(const RequestAbstractTypeImpl& src)
323 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
325 setMinorVersion(src.m_MinorVersion);
326 setRequestID(src.getRequestID());
327 setIssueInstant(src.getIssueInstant());
328 if (src.getSignature())
329 setSignature(src.getSignature()->cloneSignature());
330 VectorOf(RespondWith) v=getRespondWiths();
331 for (vector<RespondWith*>::const_iterator i=src.m_RespondWiths.begin(); i!=src.m_RespondWiths.end(); i++) {
333 v.push_back((*i)->cloneRespondWith());
338 //IMPL_TYPED_CHILD(Signature);
339 // Need customized setter.
341 Signature* m_Signature;
342 list<XMLObject*>::iterator m_pos_Signature;
344 Signature* getSignature() const {
348 void setSignature(Signature* sig) {
349 prepareForAssignment(m_Signature,sig);
350 *m_pos_Signature=m_Signature=sig;
351 // Sync content reference back up.
352 if (m_Signature && (!m_RequestID || *m_RequestID!=chDigit_0))
353 m_Signature->setContentReference(new opensaml::ContentReference(*this));
356 IMPL_INTEGER_ATTRIB(MinorVersion);
357 IMPL_STRING_ATTRIB(RequestID); // have to special-case getXMLID
358 const XMLCh* getXMLID() const {
359 pair<bool,int> v = getMinorVersion();
360 return (!v.first || v.second > 0) ? m_RequestID : NULL;
362 const XMLCh* getID() const {
363 return getRequestID();
365 IMPL_DATETIME_ATTRIB(IssueInstant,0);
366 IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature);
369 void marshallAttributes(DOMElement* domElement) const {
370 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
371 domElement->setAttributeNS(NULL,MAJORVERSION,XML_ONE);
373 const_cast<RequestAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
374 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
376 const_cast<RequestAbstractTypeImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
377 domElement->setAttributeNS(NULL, REQUESTID_ATTRIB_NAME, m_RequestID);
\r
378 if (*m_MinorVersion!=chDigit_0)
\r
379 domElement->setIdAttributeNS(NULL, REQUESTID_ATTRIB_NAME);
\r
380 if (!m_IssueInstant) {
381 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(NULL);
382 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
384 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
387 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
388 PROC_TYPED_CHILDREN(RespondWith,SAML1P_NS,false);
389 PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
390 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
393 void unmarshallAttributes(const DOMElement* domElement) {
394 // Standard processing, but then we check IDness.
395 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
396 if (m_RequestID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0))
397 const_cast<DOMElement*>(domElement)->setIdAttributeNS(NULL, REQUESTID_ATTRIB_NAME);
400 void processAttribute(const DOMAttr* attribute) {
401 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
402 if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) {
403 if (!XMLString::equals(attribute->getValue(),XML_ONE))
404 throw UnmarshallingException("Request has invalid major version.");
406 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
407 PROC_STRING_ATTRIB(RequestID,REQUESTID,NULL);
408 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
412 class SAML_DLLLOCAL RequestImpl : public virtual Request, public RequestAbstractTypeImpl
415 m_children.push_back(NULL);
417 m_pos_Query=m_pos_Signature;
421 virtual ~RequestImpl() {}
423 RequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
424 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
428 RequestImpl(const RequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
431 setQuery(src.getQuery()->cloneQuery());
432 VectorOf(AssertionIDReference) v=getAssertionIDReferences();
433 for (vector<AssertionIDReference*>::const_iterator i=src.m_AssertionIDReferences.begin(); i!=src.m_AssertionIDReferences.end(); i++) {
435 v.push_back((*i)->cloneAssertionIDReference());
438 VectorOf(AssertionArtifact) v2=getAssertionArtifacts();
439 for (vector<AssertionArtifact*>::const_iterator i=src.m_AssertionArtifacts.begin(); i!=src.m_AssertionArtifacts.end(); i++) {
441 v2.push_back((*i)->cloneAssertionArtifact());
446 IMPL_XMLOBJECT_CLONE(Request);
447 RequestAbstractType* cloneRequestAbstractType() const {
448 return cloneRequest();
450 IMPL_TYPED_CHILD(Query);
452 SubjectQuery* getSubjectQuery() const {
453 return dynamic_cast<SubjectQuery*>(getQuery());
455 AuthenticationQuery* getAuthenticationQuery() const {
456 return dynamic_cast<AuthenticationQuery*>(getQuery());
458 AttributeQuery* getAttributeQuery() const {
459 return dynamic_cast<AttributeQuery*>(getQuery());
461 AuthorizationDecisionQuery* getAuthorizationDecisionQuery() const {
462 return dynamic_cast<AuthorizationDecisionQuery*>(getQuery());
465 void setSubjectQuery(SubjectQuery* q) {
468 void setAuthenticationQuery(AuthenticationQuery* q) {
471 void setAttributeQuery(AttributeQuery* q) {
474 void setAuthorizationDecisionQuery(AuthorizationDecisionQuery* q) {
478 IMPL_TYPED_CHILDREN(AssertionIDReference, m_children.end());
479 IMPL_TYPED_CHILDREN(AssertionArtifact, m_children.end());
482 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
483 PROC_TYPED_CHILD(Query,SAML1P_NS,true);
484 PROC_TYPED_CHILDREN(AssertionIDReference,SAML1_NS,false);
485 PROC_TYPED_CHILDREN(AssertionArtifact,SAML1P_NS,false);
486 RequestAbstractTypeImpl::processChildElement(childXMLObject,root);
490 class SAML_DLLLOCAL StatusCodeImpl : public virtual StatusCode,
491 public AbstractComplexElement,
492 public AbstractDOMCachingXMLObject,
493 public AbstractXMLObjectMarshaller,
494 public AbstractXMLObjectUnmarshaller
498 m_children.push_back(NULL);
500 m_pos_StatusCode=m_children.begin();
503 virtual ~StatusCodeImpl() {
507 StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
508 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
512 StatusCodeImpl(const StatusCodeImpl& src)
513 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
515 setValue(src.getValue());
516 if (src.getStatusCode())
517 setStatusCode(src.getStatusCode()->cloneStatusCode());
520 IMPL_XMLOBJECT_CLONE(StatusCode);
521 IMPL_XMLOBJECT_ATTRIB(Value,QName);
522 IMPL_TYPED_CHILD(StatusCode);
525 void marshallAttributes(DOMElement* domElement) const {
526 MARSHALL_QNAME_ATTRIB(Value,VALUE,NULL);
529 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
530 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,true);
531 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
534 void processAttribute(const DOMAttr* attribute) {
535 PROC_QNAME_ATTRIB(Value,VALUE,NULL);
539 class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail,
540 public AbstractComplexElement,
541 public AbstractDOMCachingXMLObject,
542 public AbstractXMLObjectMarshaller,
543 public AbstractXMLObjectUnmarshaller
546 virtual ~StatusDetailImpl() {}
548 StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
549 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
552 StatusDetailImpl(const StatusDetailImpl& src)
553 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
554 VectorOf(XMLObject) v=getUnknownXMLObjects();
555 for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
556 v.push_back((*i)->clone());
559 IMPL_XMLOBJECT_CLONE(StatusDetail);
560 IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
563 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
564 getUnknownXMLObjects().push_back(childXMLObject);
568 class SAML_DLLLOCAL StatusImpl : public virtual Status,
569 public AbstractComplexElement,
570 public AbstractDOMCachingXMLObject,
571 public AbstractXMLObjectMarshaller,
572 public AbstractXMLObjectUnmarshaller
575 m_children.push_back(NULL);
576 m_children.push_back(NULL);
577 m_children.push_back(NULL);
579 m_pos_StatusCode=m_children.begin();
580 m_StatusMessage=NULL;
581 m_pos_StatusMessage=m_pos_StatusCode;
582 ++m_pos_StatusMessage;
584 m_pos_StatusDetail=m_pos_StatusMessage;
585 ++m_pos_StatusDetail;
588 virtual ~StatusImpl() {}
590 StatusImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
591 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
595 StatusImpl(const StatusImpl& src)
596 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
598 if (src.getStatusCode())
599 setStatusCode(src.getStatusCode()->cloneStatusCode());
600 if (src.getStatusMessage())
601 setStatusMessage(src.getStatusMessage()->cloneStatusMessage());
602 if (src.getStatusDetail())
603 setStatusDetail(src.getStatusDetail()->cloneStatusDetail());
606 IMPL_XMLOBJECT_CLONE(Status);
607 IMPL_TYPED_CHILD(StatusCode);
608 IMPL_TYPED_CHILD(StatusMessage);
609 IMPL_TYPED_CHILD(StatusDetail);
612 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
613 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,false);
614 PROC_TYPED_CHILD(StatusMessage,SAML1P_NS,false);
615 PROC_TYPED_CHILD(StatusDetail,SAML1P_NS,false);
616 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
620 class SAML_DLLLOCAL ResponseAbstractTypeImpl : public virtual ResponseAbstractType,
621 public AbstractComplexElement,
622 public AbstractDOMCachingXMLObject,
623 public AbstractXMLObjectMarshaller,
624 public AbstractXMLObjectUnmarshaller
632 m_children.push_back(NULL);
634 m_pos_Signature=m_children.begin();
637 ResponseAbstractTypeImpl() {
641 virtual ~ResponseAbstractTypeImpl() {
642 XMLString::release(&m_MinorVersion);
643 XMLString::release(&m_ResponseID);
644 XMLString::release(&m_InResponseTo);
645 XMLString::release(&m_Recipient);
646 delete m_IssueInstant;
649 ResponseAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
650 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
654 ResponseAbstractTypeImpl(const ResponseAbstractTypeImpl& src)
655 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
657 setMinorVersion(src.m_MinorVersion);
658 setResponseID(src.getResponseID());
659 setInResponseTo(src.getInResponseTo());
660 setIssueInstant(src.getIssueInstant());
661 setRecipient(src.getRecipient());
662 if (src.getSignature())
663 setSignature(src.getSignature()->cloneSignature());
666 //IMPL_TYPED_CHILD(Signature);
667 // Need customized setter.
669 Signature* m_Signature;
670 list<XMLObject*>::iterator m_pos_Signature;
672 Signature* getSignature() const {
676 void setSignature(Signature* sig) {
677 prepareForAssignment(m_Signature,sig);
678 *m_pos_Signature=m_Signature=sig;
679 // Sync content reference back up.
680 if (m_Signature && (!m_ResponseID || *m_ResponseID!=chDigit_0))
681 m_Signature->setContentReference(new opensaml::ContentReference(*this));
684 IMPL_INTEGER_ATTRIB(MinorVersion);
685 IMPL_STRING_ATTRIB(ResponseID); // have to special-case getXMLID
686 const XMLCh* getXMLID() const {
687 pair<bool,int> v = getMinorVersion();
688 return (!v.first || v.second > 0) ? m_ResponseID : NULL;
690 const XMLCh* getID() const {
691 return getResponseID();
693 IMPL_STRING_ATTRIB(InResponseTo);
694 IMPL_DATETIME_ATTRIB(IssueInstant,0);
695 IMPL_STRING_ATTRIB(Recipient);
698 void marshallAttributes(DOMElement* domElement) const {
699 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
700 domElement->setAttributeNS(NULL,MAJORVERSION,XML_ONE);
702 const_cast<ResponseAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
703 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
705 const_cast<ResponseAbstractTypeImpl*>(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier();
706 domElement->setAttributeNS(NULL, RESPONSEID_ATTRIB_NAME, m_ResponseID);
\r
707 if (*m_MinorVersion!=chDigit_0)
\r
708 domElement->setIdAttributeNS(NULL, RESPONSEID_ATTRIB_NAME);
\r
709 MARSHALL_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL);
710 if (!m_IssueInstant) {
711 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(NULL);
712 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
714 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
715 MARSHALL_STRING_ATTRIB(Recipient,RECIPIENT,NULL);
718 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
719 PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
720 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
723 void unmarshallAttributes(const DOMElement* domElement) {
724 // Standard processing, but then we check IDness.
725 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
726 if (m_ResponseID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0))
727 const_cast<DOMElement*>(domElement)->setIdAttributeNS(NULL, RESPONSEID_ATTRIB_NAME);
730 void processAttribute(const DOMAttr* attribute) {
731 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
732 if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) {
733 if (!XMLString::equals(attribute->getValue(),XML_ONE))
734 throw UnmarshallingException("Response has invalid major version.");
736 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
737 PROC_STRING_ATTRIB(ResponseID,RESPONSEID,NULL);
738 PROC_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL);
739 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
740 PROC_STRING_ATTRIB(Recipient,RECIPIENT,NULL);
744 class SAML_DLLLOCAL ResponseImpl : public virtual Response, public ResponseAbstractTypeImpl
747 m_children.push_back(NULL);
749 m_pos_Status=m_pos_Signature;
753 virtual ~ResponseImpl() {}
755 ResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
756 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
760 ResponseImpl(const ResponseImpl& src) : AbstractXMLObject(src), ResponseAbstractTypeImpl(src) {
763 setStatus(src.getStatus()->cloneStatus());
764 VectorOf(saml1::Assertion) v=getAssertions();
765 for (vector<saml1::Assertion*>::const_iterator i=src.m_Assertions.begin(); i!=src.m_Assertions.end(); i++) {
767 v.push_back((*i)->cloneAssertion());
772 IMPL_XMLOBJECT_CLONE(Response);
773 ResponseAbstractType* cloneResponseAbstractType() const {
774 return cloneResponse();
776 IMPL_TYPED_CHILD(Status);
777 IMPL_TYPED_FOREIGN_CHILDREN(Assertion,saml1,m_children.end());
780 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
781 PROC_TYPED_CHILD(Status,SAML1P_NS,false);
782 PROC_TYPED_FOREIGN_CHILDREN(Assertion,saml1,SAML1_NS,true);
783 ResponseAbstractTypeImpl::processChildElement(childXMLObject,root);
790 #if defined (_MSC_VER)
791 #pragma warning( pop )
794 // Builder Implementations
796 IMPL_XMLOBJECTBUILDER(AssertionArtifact);
797 IMPL_XMLOBJECTBUILDER(AttributeQuery);
798 IMPL_XMLOBJECTBUILDER(AuthenticationQuery);
799 IMPL_XMLOBJECTBUILDER(AuthorizationDecisionQuery);
800 IMPL_XMLOBJECTBUILDER(Request);
801 IMPL_XMLOBJECTBUILDER(RespondWith);
802 IMPL_XMLOBJECTBUILDER(Response);
803 IMPL_XMLOBJECTBUILDER(Status);
804 IMPL_XMLOBJECTBUILDER(StatusCode);
805 IMPL_XMLOBJECTBUILDER(StatusDetail);
806 IMPL_XMLOBJECTBUILDER(StatusMessage);
809 const XMLCh RequestAbstractType::LOCAL_NAME[] = {chNull};
810 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);
811 const XMLCh RequestAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
812 const XMLCh RequestAbstractType::REQUESTID_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,I,D);
813 const XMLCh RequestAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
814 const XMLCh ResponseAbstractType::LOCAL_NAME[] = {chNull};
815 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);
816 const XMLCh ResponseAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
817 const XMLCh ResponseAbstractType::RESPONSEID_ATTRIB_NAME[] = UNICODE_LITERAL_10(R,e,s,p,o,n,s,e,I,D);
818 const XMLCh ResponseAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
819 const XMLCh ResponseAbstractType::INRESPONSETO_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,n,R,e,s,p,o,n,s,e,T,o);
820 const XMLCh ResponseAbstractType::RECIPIENT_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,c,i,p,i,e,n,t);
821 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);
822 const XMLCh AttributeQuery::LOCAL_NAME[] = UNICODE_LITERAL_14(A,t,t,r,i,b,u,t,e,Q,u,e,r,y);
823 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);
824 const XMLCh AttributeQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
825 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);
826 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);
827 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);
828 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);
829 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);
830 const XMLCh AuthorizationDecisionQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
831 const XMLCh Query::LOCAL_NAME[] = UNICODE_LITERAL_5(Q,u,e,r,y);
832 const XMLCh Request::LOCAL_NAME[] = UNICODE_LITERAL_7(R,e,q,u,e,s,t);
833 const XMLCh Request::TYPE_NAME[] = UNICODE_LITERAL_11(R,e,q,u,e,s,t,T,y,p,e);
834 const XMLCh RespondWith::LOCAL_NAME[] = UNICODE_LITERAL_11(R,e,s,p,o,n,d,W,i,t,h);
835 const XMLCh Response::LOCAL_NAME[] = UNICODE_LITERAL_8(R,e,s,p,o,n,s,e);
836 const XMLCh Response::TYPE_NAME[] = UNICODE_LITERAL_12(R,e,s,p,o,n,s,e,T,y,p,e);
837 const XMLCh Status::LOCAL_NAME[] = UNICODE_LITERAL_6(S,t,a,t,u,s);
838 const XMLCh Status::TYPE_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,T,y,p,e);
839 const XMLCh StatusCode::LOCAL_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,C,o,d,e);
840 const XMLCh StatusCode::TYPE_NAME[] = UNICODE_LITERAL_14(S,t,a,t,u,s,C,o,d,e,T,y,p,e);
841 const XMLCh StatusCode::VALUE_ATTRIB_NAME[] = UNICODE_LITERAL_5(V,a,l,u,e);
842 const XMLCh StatusDetail::LOCAL_NAME[] = UNICODE_LITERAL_12(S,t,a,t,u,s,D,e,t,a,i,l);
843 const XMLCh StatusDetail::TYPE_NAME[] = UNICODE_LITERAL_16(S,t,a,t,u,s,D,e,t,a,i,l,T,y,p,e);
844 const XMLCh StatusMessage::LOCAL_NAME[] = UNICODE_LITERAL_13(S,t,a,t,u,s,M,e,s,s,a,g,e);
845 const XMLCh SubjectQuery::LOCAL_NAME[] = UNICODE_LITERAL_12(S,u,b,j,e,c,t,Q,u,e,r,y);
847 #define XCH(ch) chLatin_##ch
848 #define XNUM(d) chDigit_##d
850 const XMLCh _SUCCESS[] = UNICODE_LITERAL_7(S,u,c,c,e,s,s);
851 const XMLCh _REQUESTER[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,e,r);
852 const XMLCh _RESPONDER[] = UNICODE_LITERAL_9(R,e,s,p,o,n,d,e,r);
853 const XMLCh _VERSIONMISMATCH[] = UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h);
855 QName StatusCode::SUCCESS(SAML1P_NS,_SUCCESS,SAML1P_PREFIX);
856 QName StatusCode::REQUESTER(SAML1P_NS,_REQUESTER,SAML1P_PREFIX);
857 QName StatusCode::RESPONDER(SAML1P_NS,_RESPONDER,SAML1P_PREFIX);
858 QName StatusCode::VERSIONMISMATCH(SAML1P_NS,_VERSIONMISMATCH,SAML1P_PREFIX);