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