ee6969b85a9181e516624fe116bb0d984403581e
[shibboleth/cpp-opensaml.git] / saml / saml1 / core / impl / ProtocolsImpl.cpp
1 /*
2  *  Copyright 2001-2006 Internet2
3  * 
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /**
18  * ProtocolsImpl.cpp
19  * 
20  * Implementation classes for SAML 1.x Protocols schema
21  */
22
23 #include "internal.h"
24 #include "exceptions.h"
25 #include "saml1/core/Protocols.h"
26
27 #include <xmltooling/AbstractChildlessElement.h>
28 #include <xmltooling/AbstractComplexElement.h>
29 #include <xmltooling/AbstractElementProxy.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/util/XMLHelper.h>
35 #include <xmltooling/validation/AbstractValidatingXMLObject.h>
36
37 #include <ctime>
38 #include <xercesc/util/XMLUniDefs.hpp>
39
40 using namespace opensaml::saml1p;
41 using namespace opensaml::saml1;
42 using namespace opensaml;
43 using namespace xmlsignature;
44 using namespace xmltooling;
45 using namespace std;
46
47 #if defined (_MSC_VER)
48     #pragma warning( push )
49     #pragma warning( disable : 4250 4251 )
50 #endif
51
52 namespace opensaml {
53     namespace saml1p {
54     
55         DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,AssertionArtifact);
56         DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,StatusMessage);
57
58         class SAML_DLLLOCAL RespondWithImpl : public virtual RespondWith,
59             protected AbstractSimpleElement,
60             public AbstractChildlessElement,
61             public AbstractDOMCachingXMLObject,
62             public AbstractValidatingXMLObject,
63             public AbstractXMLObjectMarshaller,
64             public AbstractXMLObjectUnmarshaller
65         {
66             QName* m_qname;
67         public:
68             virtual ~RespondWithImpl() {
69                 delete m_qname;
70             }
71     
72             RespondWithImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
73                 : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_qname(NULL) {
74             }
75                 
76             RespondWithImpl(const RespondWithImpl& src)
77                     : AbstractXMLObject(src),
78                         AbstractSimpleElement(src),
79                         AbstractDOMCachingXMLObject(src),
80                         AbstractValidatingXMLObject(src), m_qname(NULL) {
81                 setQName(src.getQName());
82             }
83             
84             QName* getQName() const {
85                 return m_qname;
86             }
87             
88             void setQName(const QName* qname) {
89                 m_qname=prepareForAssignment(m_qname,qname);
90                 if (m_qname) {
91                     auto_ptr_XMLCh temp(m_qname->toString().c_str());
92                     setTextContent(temp.get());
93                 }
94                 else
95                     setTextContent(NULL);
96             }
97             
98             IMPL_XMLOBJECT_CLONE(RespondWith);
99             IMPL_XMLOBJECT_CONTENT;
100         };
101
102         class SAML_DLLLOCAL SubjectQueryImpl : public virtual SubjectQuery,
103             public AbstractComplexElement,
104             public AbstractDOMCachingXMLObject,
105             public AbstractValidatingXMLObject,
106             public AbstractXMLObjectMarshaller,
107             public AbstractXMLObjectUnmarshaller
108         {
109             void init() {
110                 m_Subject=NULL;
111                 m_children.push_back(NULL);
112                 m_pos_Subject=m_children.begin();
113             }
114         protected:
115             SubjectQueryImpl() {
116                 init();
117             }
118         public:
119             virtual ~SubjectQueryImpl() {}
120     
121             SubjectQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
122                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
123                 init();
124             }
125                 
126             SubjectQueryImpl(const SubjectQueryImpl& src)
127                     : AbstractXMLObject(src),
128                         AbstractDOMCachingXMLObject(src),
129                         AbstractValidatingXMLObject(src) {
130                 init();
131                 if (src.getSubject())
132                     setSubject(src.getSubject()->cloneSubject());
133             }
134             
135             IMPL_TYPED_CHILD(Subject);
136     
137         protected:
138             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
139                 PROC_TYPED_CHILD(Subject,SAMLConstants::SAML1_NS,true);
140                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
141             }
142         };
143
144         class SAML_DLLLOCAL AuthenticationQueryImpl : public virtual AuthenticationQuery, public SubjectQueryImpl
145         {
146             void init() {
147                 m_AuthenticationMethod=NULL;
148             }
149         public:
150             virtual ~AuthenticationQueryImpl() {
151                 XMLString::release(&m_AuthenticationMethod);
152             }
153     
154             AuthenticationQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
155                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
156                 init();
157             }
158                 
159             AuthenticationQueryImpl(const AuthenticationQueryImpl& src)
160                     : AbstractXMLObject(src), SubjectQueryImpl(src) {
161                 init();
162                 setAuthenticationMethod(src.getAuthenticationMethod());
163             }
164             
165             IMPL_XMLOBJECT_CLONE(AuthenticationQuery);
166             SubjectQuery* cloneSubjectQuery() const {
167                 return cloneAuthenticationQuery();
168             }
169             Query* cloneQuery() const {
170                 return cloneAuthenticationQuery();
171             }
172             IMPL_STRING_ATTRIB(AuthenticationMethod);
173     
174         protected:
175             void marshallAttributes(DOMElement* domElement) const {
176                 MARSHALL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL);
177                 SubjectQueryImpl::marshallAttributes(domElement);
178             }
179     
180             void processAttribute(const DOMAttr* attribute) {
181                 PROC_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL);
182                 SubjectQueryImpl::processAttribute(attribute);
183             }
184         };
185
186         class SAML_DLLLOCAL AttributeQueryImpl : public virtual AttributeQuery, public SubjectQueryImpl
187         {
188             void init() {
189                 m_Resource=NULL;
190             }
191         public:
192             virtual ~AttributeQueryImpl() {
193                 XMLString::release(&m_Resource);
194             }
195     
196             AttributeQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
197                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
198                 init();
199             }
200                 
201             AttributeQueryImpl(const AttributeQueryImpl& src)
202                     : AbstractXMLObject(src), SubjectQueryImpl(src) {
203                 init();
204                 setResource(src.getResource());
205                 VectorOf(AttributeDesignator) v=getAttributeDesignators();
206                 for (vector<AttributeDesignator*>::const_iterator i=src.m_AttributeDesignators.begin(); i!=src.m_AttributeDesignators.end(); i++) {
207                     if (*i) {
208                         v.push_back((*i)->cloneAttributeDesignator());
209                     }
210                 }
211             }
212             
213             IMPL_XMLOBJECT_CLONE(AttributeQuery);
214             SubjectQuery* cloneSubjectQuery() const {
215                 return cloneAttributeQuery();
216             }
217             Query* cloneQuery() const {
218                 return cloneAttributeQuery();
219             }
220             IMPL_STRING_ATTRIB(Resource);
221             IMPL_TYPED_CHILDREN(AttributeDesignator,m_children.end());
222     
223         protected:
224             void marshallAttributes(DOMElement* domElement) const {
225                 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,NULL);
226                 SubjectQueryImpl::marshallAttributes(domElement);
227             }
228     
229             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
230                 PROC_TYPED_CHILDREN(AttributeDesignator,SAMLConstants::SAML1_NS,true);
231                 SubjectQueryImpl::processChildElement(childXMLObject,root);
232             }
233     
234             void processAttribute(const DOMAttr* attribute) {
235                 PROC_STRING_ATTRIB(Resource,RESOURCE,NULL);
236                 SubjectQueryImpl::processAttribute(attribute);
237             }
238         };
239
240         class SAML_DLLLOCAL AuthorizationDecisionQueryImpl : public virtual AuthorizationDecisionQuery, public SubjectQueryImpl
241         {
242             void init() {
243                 m_Resource=NULL;
244                 m_Evidence=NULL;
245                 m_children.push_back(NULL);
246                 m_pos_Evidence=m_pos_Subject;
247                 ++m_pos_Evidence;
248             }
249         public:
250             virtual ~AuthorizationDecisionQueryImpl() {
251                 XMLString::release(&m_Resource);
252             }
253     
254             AuthorizationDecisionQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
255                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
256                 init();
257             }
258                 
259             AuthorizationDecisionQueryImpl(const AuthorizationDecisionQueryImpl& src)
260                     : AbstractXMLObject(src), SubjectQueryImpl(src) {
261                 init();
262                 setResource(src.getResource());
263                 if (src.getEvidence())
264                     setEvidence(src.getEvidence()->cloneEvidence());
265                 VectorOf(Action) v=getActions();
266                 for (vector<Action*>::const_iterator i=src.m_Actions.begin(); i!=src.m_Actions.end(); i++) {
267                     if (*i) {
268                         v.push_back((*i)->cloneAction());
269                     }
270                 }
271             }
272             
273             IMPL_XMLOBJECT_CLONE(AuthorizationDecisionQuery);
274             SubjectQuery* cloneSubjectQuery() const {
275                 return cloneAuthorizationDecisionQuery();
276             }
277             Query* cloneQuery() const {
278                 return cloneAuthorizationDecisionQuery();
279             }
280             IMPL_STRING_ATTRIB(Resource);
281             IMPL_TYPED_CHILD(Evidence);
282             IMPL_TYPED_CHILDREN(Action, m_pos_Evidence);
283     
284         protected:
285             void marshallAttributes(DOMElement* domElement) const {
286                 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,NULL);
287                 SubjectQueryImpl::marshallAttributes(domElement);
288             }
289     
290             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
291                 PROC_TYPED_CHILD(Evidence,SAMLConstants::SAML1_NS,false);
292                 PROC_TYPED_CHILDREN(Action,SAMLConstants::SAML1_NS,false);
293                 SubjectQueryImpl::processChildElement(childXMLObject,root);
294             }
295     
296             void processAttribute(const DOMAttr* attribute) {
297                 PROC_STRING_ATTRIB(Resource,RESOURCE,NULL);
298                 SubjectQueryImpl::processAttribute(attribute);
299             }
300         };
301
302         class SAML_DLLLOCAL RequestAbstractTypeImpl : public virtual RequestAbstractType,
303             public AbstractComplexElement,
304             public AbstractDOMCachingXMLObject,
305             public AbstractValidatingXMLObject,
306             public AbstractXMLObjectMarshaller,
307             public AbstractXMLObjectUnmarshaller
308         {
309             void init() {
310                 m_MinorVersion=NULL;
311                 m_RequestID=NULL;
312                 m_IssueInstant=NULL;
313                 m_children.push_back(NULL);
314                 m_Signature=NULL;
315                 m_pos_Signature=m_children.begin();
316             }
317         protected:
318             RequestAbstractTypeImpl() {
319                 init();
320             }
321         public:
322             virtual ~RequestAbstractTypeImpl() {
323                 XMLString::release(&m_MinorVersion);
324                 XMLString::release(&m_RequestID);
325                 delete m_IssueInstant;
326             }
327     
328             RequestAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
329                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
330                 init();
331             }
332                 
333             RequestAbstractTypeImpl(const RequestAbstractTypeImpl& src)
334                     : AbstractXMLObject(src),
335                         AbstractDOMCachingXMLObject(src),
336                         AbstractValidatingXMLObject(src) {
337                 init();
338                 setMinorVersion(src.m_MinorVersion);
339                 setRequestID(src.getRequestID());
340                 setIssueInstant(src.getIssueInstant());
341                 if (src.getSignature())
342                     setSignature(src.getSignature()->cloneSignature());
343                 VectorOf(RespondWith) v=getRespondWiths();
344                 for (vector<RespondWith*>::const_iterator i=src.m_RespondWiths.begin(); i!=src.m_RespondWiths.end(); i++) {
345                     if (*i) {
346                         v.push_back((*i)->cloneRespondWith());
347                     }
348                 }
349             }
350             
351             const XMLCh* getId() const {
352                 return getRequestID();
353             }
354
355             //IMPL_TYPED_CHILD(Signature);
356             // Need customized setter.
357         protected:
358             Signature* m_Signature;
359             list<XMLObject*>::iterator m_pos_Signature;
360         public:
361             Signature* getSignature() const {
362                 return m_Signature;
363             }
364             
365             void setSignature(Signature* sig) {
366                 prepareForAssignment(m_Signature,sig);
367                 *m_pos_Signature=m_Signature=sig;
368                 // Sync content reference back up.
369                 if (m_Signature)
370                     m_Signature->setContentReference(new opensaml::ContentReference(*this));
371             }
372
373             IMPL_INTEGER_ATTRIB(MinorVersion);
374             IMPL_STRING_ATTRIB(RequestID);
375             IMPL_DATETIME_ATTRIB(IssueInstant,0);
376             IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature);
377     
378         protected:
379             void marshallAttributes(DOMElement* domElement) const {
380                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
381                 domElement->setAttributeNS(NULL,MAJORVERSION,XMLConstants::XML_ONE);
382                 if (!m_MinorVersion)
383                     const_cast<RequestAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XMLConstants::XML_ONE);
384                 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
385                 if (!m_RequestID)
386                     const_cast<RequestAbstractTypeImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
387                 MARSHALL_ID_ATTRIB(RequestID,REQUESTID,NULL);
388                 if (!m_IssueInstant) {
389                     const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(NULL);
390                     const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
391                 }
392                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
393             }
394
395             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
396                 PROC_TYPED_CHILDREN(RespondWith,SAMLConstants::SAML1P_NS,false);
397                 PROC_TYPED_CHILD(Signature,XMLConstants::XMLSIG_NS,false);
398                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
399             }
400
401             void processAttribute(const DOMAttr* attribute) {
402                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
403                 if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) {
404                     if (!XMLString::equals(attribute->getValue(),XMLConstants::XML_ONE))
405                         throw UnmarshallingException("Request has invalid major version.");
406                 }
407                 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
408                 PROC_ID_ATTRIB(RequestID,REQUESTID,NULL);
409                 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
410             }
411         };
412
413         class SAML_DLLLOCAL RequestImpl : public virtual Request, public RequestAbstractTypeImpl
414         {
415             void init() {
416                 m_children.push_back(NULL);
417                 m_Query=NULL;
418                 m_pos_Query=m_pos_Signature;
419                 ++m_pos_Query;
420             }
421         public:
422             virtual ~RequestImpl() {}
423     
424             RequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
425                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
426                 init();
427             }
428                 
429             RequestImpl(const RequestImpl& src)
430                     : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
431                 init();
432                 if (src.getQuery())
433                     setQuery(src.getQuery()->cloneQuery());
434                 VectorOf(AssertionIDReference) v=getAssertionIDReferences();
435                 for (vector<AssertionIDReference*>::const_iterator i=src.m_AssertionIDReferences.begin(); i!=src.m_AssertionIDReferences.end(); i++) {
436                     if (*i) {
437                         v.push_back((*i)->cloneAssertionIDReference());
438                     }
439                 }
440                 VectorOf(AssertionArtifact) v2=getAssertionArtifacts();
441                 for (vector<AssertionArtifact*>::const_iterator i=src.m_AssertionArtifacts.begin(); i!=src.m_AssertionArtifacts.end(); i++) {
442                     if (*i) {
443                         v2.push_back((*i)->cloneAssertionArtifact());
444                     }
445                 }
446             }
447             
448             IMPL_XMLOBJECT_CLONE(Request);
449             RequestAbstractType* cloneRequestAbstractType() const {
450                 return cloneRequest();
451             }
452             IMPL_TYPED_CHILD(Query);
453             
454             SubjectQuery* getSubjectQuery() const {
455                 return dynamic_cast<SubjectQuery*>(getQuery());
456             }
457             AuthenticationQuery* getAuthenticationQuery() const {
458                 return dynamic_cast<AuthenticationQuery*>(getQuery());
459             }
460             AttributeQuery* getAttributeQuery() const {
461                 return dynamic_cast<AttributeQuery*>(getQuery());
462             }
463             AuthorizationDecisionQuery* getAuthorizationDecisionQuery() const {
464                 return dynamic_cast<AuthorizationDecisionQuery*>(getQuery());
465             }
466
467             void setSubjectQuery(SubjectQuery* q) {
468                 setQuery(q);
469             }
470             void setAuthenticationQuery(AuthenticationQuery* q) {
471                 setQuery(q);
472             }
473             void setAttributeQuery(AttributeQuery* q) {
474                 setQuery(q);
475             }
476             void setAuthorizationDecisionQuery(AuthorizationDecisionQuery* q) {
477                 setQuery(q);
478             }
479             
480             IMPL_TYPED_CHILDREN(AssertionIDReference, m_children.end());
481             IMPL_TYPED_CHILDREN(AssertionArtifact, m_children.end());
482     
483         protected:
484             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
485                 PROC_TYPED_CHILD(Query,SAMLConstants::SAML1P_NS,true);
486                 PROC_TYPED_CHILDREN(AssertionIDReference,SAMLConstants::SAML1_NS,false);
487                 PROC_TYPED_CHILDREN(AssertionArtifact,SAMLConstants::SAML1P_NS,false);
488                 RequestAbstractTypeImpl::processChildElement(childXMLObject,root);
489             }
490         };
491
492         class SAML_DLLLOCAL StatusCodeImpl : public virtual StatusCode,
493             public AbstractComplexElement,
494             public AbstractDOMCachingXMLObject,
495             public AbstractValidatingXMLObject,
496             public AbstractXMLObjectMarshaller,
497             public AbstractXMLObjectUnmarshaller
498         {
499             void init() {
500                 m_Value=NULL;
501                 m_children.push_back(NULL);
502                 m_StatusCode=NULL;
503                 m_pos_StatusCode=m_children.begin();
504             }
505         public:
506             virtual ~StatusCodeImpl() {
507                 delete m_Value;
508             }
509     
510             StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
511                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
512                 init();
513             }
514                 
515             StatusCodeImpl(const StatusCodeImpl& src)
516                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
517                 init();
518                 setValue(src.getValue());
519                 if (src.getStatusCode())
520                     setStatusCode(src.getStatusCode()->cloneStatusCode());
521             }
522             
523             IMPL_XMLOBJECT_CLONE(StatusCode);
524             IMPL_XMLOBJECT_ATTRIB(Value,QName);
525             IMPL_TYPED_CHILD(StatusCode);
526     
527         protected:
528             void marshallAttributes(DOMElement* domElement) const {
529                 MARSHALL_QNAME_ATTRIB(Value,VALUE,NULL);
530             }
531
532             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
533                 PROC_TYPED_CHILD(StatusCode,SAMLConstants::SAML1P_NS,true);
534                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
535             }
536
537             void processAttribute(const DOMAttr* attribute) {
538                 PROC_QNAME_ATTRIB(Value,VALUE,NULL);
539             }
540         };
541
542         class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail,
543             public AbstractComplexElement,
544             public AbstractDOMCachingXMLObject,
545             public AbstractValidatingXMLObject,
546             public AbstractXMLObjectMarshaller,
547             public AbstractXMLObjectUnmarshaller
548         {
549         public:
550             virtual ~StatusDetailImpl() {}
551     
552             StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
553                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
554             }
555                 
556             StatusDetailImpl(const StatusDetailImpl& src)
557                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
558                 VectorOf(XMLObject) v=getDetails();
559                 for (vector<XMLObject*>::const_iterator i=src.m_Details.begin(); i!=src.m_Details.end(); i++) {
560                     if (*i) {
561                         v.push_back((*i)->clone());
562                     }
563                 }
564             }
565             
566             IMPL_XMLOBJECT_CLONE(StatusDetail);
567             IMPL_XMLOBJECT_CHILDREN(Detail,m_children.end());
568     
569         protected:
570             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
571                 getDetails().push_back(childXMLObject);
572             }
573         };
574
575         class SAML_DLLLOCAL StatusImpl : public virtual Status,
576             public AbstractComplexElement,
577             public AbstractDOMCachingXMLObject,
578             public AbstractValidatingXMLObject,
579             public AbstractXMLObjectMarshaller,
580             public AbstractXMLObjectUnmarshaller
581         {
582             void init() {
583                 m_children.push_back(NULL);
584                 m_children.push_back(NULL);
585                 m_children.push_back(NULL);
586                 m_StatusCode=NULL;
587                 m_pos_StatusCode=m_children.begin();
588                 m_StatusMessage=NULL;
589                 m_pos_StatusMessage=m_pos_StatusCode;
590                 ++m_pos_StatusMessage;
591                 m_StatusDetail=NULL;
592                 m_pos_StatusDetail=m_pos_StatusMessage;
593                 ++m_pos_StatusDetail;
594             }
595         public:
596             virtual ~StatusImpl() {}
597     
598             StatusImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
599                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
600                 init();
601             }
602                 
603             StatusImpl(const StatusImpl& src)
604                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
605                 init();
606                 if (src.getStatusCode())
607                     setStatusCode(src.getStatusCode()->cloneStatusCode());
608                 if (src.getStatusMessage())
609                     setStatusMessage(src.getStatusMessage()->cloneStatusMessage());
610                 if (src.getStatusDetail())
611                     setStatusDetail(src.getStatusDetail()->cloneStatusDetail());
612             }
613             
614             IMPL_XMLOBJECT_CLONE(Status);
615             IMPL_TYPED_CHILD(StatusCode);
616             IMPL_TYPED_CHILD(StatusMessage);
617             IMPL_TYPED_CHILD(StatusDetail);
618     
619         protected:
620             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
621                 PROC_TYPED_CHILD(StatusCode,SAMLConstants::SAML1P_NS,false);
622                 PROC_TYPED_CHILD(StatusMessage,SAMLConstants::SAML1P_NS,false);
623                 PROC_TYPED_CHILD(StatusDetail,SAMLConstants::SAML1P_NS,false);
624                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
625             }
626         };
627
628         class SAML_DLLLOCAL ResponseAbstractTypeImpl : public virtual ResponseAbstractType,
629             public AbstractComplexElement,
630             public AbstractDOMCachingXMLObject,
631             public AbstractValidatingXMLObject,
632             public AbstractXMLObjectMarshaller,
633             public AbstractXMLObjectUnmarshaller
634         {
635             void init() {
636                 m_MinorVersion=NULL;
637                 m_ResponseID=NULL;
638                 m_InResponseTo=NULL;
639                 m_IssueInstant=NULL;
640                 m_Recipient=NULL;
641                 m_children.push_back(NULL);
642                 m_Signature=NULL;
643                 m_pos_Signature=m_children.begin();
644             }
645         protected:
646             ResponseAbstractTypeImpl() {
647                 init();
648             }
649         public:
650             virtual ~ResponseAbstractTypeImpl() {
651                 XMLString::release(&m_MinorVersion);
652                 XMLString::release(&m_ResponseID);
653                 XMLString::release(&m_InResponseTo);
654                 XMLString::release(&m_Recipient);
655                 delete m_IssueInstant;
656             }
657     
658             ResponseAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
659                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
660                 init();
661             }
662                 
663             ResponseAbstractTypeImpl(const ResponseAbstractTypeImpl& src)
664                     : AbstractXMLObject(src),
665                         AbstractDOMCachingXMLObject(src),
666                         AbstractValidatingXMLObject(src) {
667                 init();
668                 setMinorVersion(src.m_MinorVersion);
669                 setResponseID(src.getResponseID());
670                 setInResponseTo(src.getInResponseTo());
671                 setIssueInstant(src.getIssueInstant());
672                 setRecipient(src.getRecipient());
673                 if (src.getSignature())
674                     setSignature(src.getSignature()->cloneSignature());
675             }
676
677             const XMLCh* getId() const {
678                 return getResponseID();
679             }
680
681             //IMPL_TYPED_CHILD(Signature);
682             // Need customized setter.
683         protected:
684             Signature* m_Signature;
685             list<XMLObject*>::iterator m_pos_Signature;
686         public:
687             Signature* getSignature() const {
688                 return m_Signature;
689             }
690             
691             void setSignature(Signature* sig) {
692                 prepareForAssignment(m_Signature,sig);
693                 *m_pos_Signature=m_Signature=sig;
694                 // Sync content reference back up.
695                 if (m_Signature)
696                     m_Signature->setContentReference(new opensaml::ContentReference(*this));
697             }
698
699             IMPL_INTEGER_ATTRIB(MinorVersion);
700             IMPL_STRING_ATTRIB(ResponseID);
701             IMPL_STRING_ATTRIB(InResponseTo);
702             IMPL_DATETIME_ATTRIB(IssueInstant,0);
703             IMPL_STRING_ATTRIB(Recipient);
704     
705         protected:
706             void marshallAttributes(DOMElement* domElement) const {
707                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
708                 domElement->setAttributeNS(NULL,MAJORVERSION,XMLConstants::XML_ONE);
709                 if (!m_MinorVersion)
710                     const_cast<ResponseAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XMLConstants::XML_ONE);
711                 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
712                 if (!m_ResponseID)
713                     const_cast<ResponseAbstractTypeImpl*>(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier();
714                 MARSHALL_ID_ATTRIB(ResponseID,RESPONSEID,NULL);
715                 MARSHALL_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL);
716                 if (!m_IssueInstant) {
717                     const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(NULL);
718                     const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
719                 }
720                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
721                 MARSHALL_STRING_ATTRIB(Recipient,RECIPIENT,NULL);
722             }
723
724             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
725                 PROC_TYPED_CHILD(Signature,XMLConstants::XMLSIG_NS,false);
726                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
727             }
728
729             void processAttribute(const DOMAttr* attribute) {
730                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
731                 if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) {
732                     if (!XMLString::equals(attribute->getValue(),XMLConstants::XML_ONE))
733                         throw UnmarshallingException("Response has invalid major version.");
734                 }
735                 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
736                 PROC_ID_ATTRIB(ResponseID,RESPONSEID,NULL);
737                 PROC_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL);
738                 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
739                 PROC_STRING_ATTRIB(Recipient,RECIPIENT,NULL);
740             }
741         };
742
743         class SAML_DLLLOCAL ResponseImpl : public virtual Response, public ResponseAbstractTypeImpl
744         {
745             void init() {
746                 m_children.push_back(NULL);
747                 m_Status=NULL;
748                 m_pos_Status=m_pos_Signature;
749                 ++m_pos_Status;
750             }
751         public:
752             virtual ~ResponseImpl() {}
753     
754             ResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
755                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
756                 init();
757             }
758                 
759             ResponseImpl(const ResponseImpl& src)
760                     : AbstractXMLObject(src), ResponseAbstractTypeImpl(src) {
761                 init();
762                 if (src.getStatus())
763                     setStatus(src.getStatus()->cloneStatus());
764                 VectorOf(Assertion) v=getAssertions();
765                 for (vector<Assertion*>::const_iterator i=src.m_Assertions.begin(); i!=src.m_Assertions.end(); i++) {
766                     if (*i) {
767                         v.push_back((*i)->cloneAssertion());
768                     }
769                 }
770             }
771             
772             IMPL_XMLOBJECT_CLONE(Response);
773             ResponseAbstractType* cloneResponseAbstractType() const {
774                 return cloneResponse();
775             }
776             IMPL_TYPED_CHILD(Status);
777             IMPL_TYPED_CHILDREN(Assertion, m_children.end());
778     
779         protected:
780             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
781                 PROC_TYPED_CHILD(Status,SAMLConstants::SAML1P_NS,false);
782                 PROC_TYPED_CHILDREN(Assertion,SAMLConstants::SAML1_NS,true);
783                 ResponseAbstractTypeImpl::processChildElement(childXMLObject,root);
784             }
785         };
786
787     };
788 };
789
790 #if defined (_MSC_VER)
791     #pragma warning( pop )
792 #endif
793
794 // Builder Implementations
795
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);
807
808 // Unicode literals
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);
846
847 #define XCH(ch) chLatin_##ch
848 #define XNUM(d) chDigit_##d
849
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);
854  
855 QName StatusCode::SUCCESS(SAMLConstants::SAML1P_NS,_SUCCESS,SAMLConstants::SAML1P_PREFIX);
856 QName StatusCode::REQUESTER(SAMLConstants::SAML1P_NS,_REQUESTER,SAMLConstants::SAML1P_PREFIX);
857 QName StatusCode::RESPONDER(SAMLConstants::SAML1P_NS,_RESPONDER,SAMLConstants::SAML1P_PREFIX);
858 QName StatusCode::VERSIONMISMATCH(SAMLConstants::SAML1P_NS,_VERSIONMISMATCH,SAMLConstants::SAML1P_PREFIX);