Completed 2.0 assertions schema classes.
[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 AbstractRequestImpl : public virtual AbstractRequest,
303             public AbstractComplexElement,
304             public AbstractDOMCachingXMLObject,
305             public AbstractValidatingXMLObject,
306             public AbstractXMLObjectMarshaller,
307             public AbstractXMLObjectUnmarshaller
308         {
309             void init() {
310                 m_MinorVersion=1;
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             AbstractRequestImpl() {
319                 init();
320             }
321         public:
322             virtual ~AbstractRequestImpl() {
323                 XMLString::release(&m_RequestID);
324                 delete m_IssueInstant;
325             }
326     
327             AbstractRequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
328                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
329                 init();
330             }
331                 
332             AbstractRequestImpl(const AbstractRequestImpl& src)
333                     : AbstractXMLObject(src),
334                         AbstractDOMCachingXMLObject(src),
335                         AbstractValidatingXMLObject(src) {
336                 init();
337                 setMinorVersion(src.getMinorVersion());
338                 setRequestID(src.getRequestID());
339                 setIssueInstant(src.getIssueInstant());
340                 if (src.getSignature())
341                     setSignature(src.getSignature()->cloneSignature());
342                 VectorOf(RespondWith) v=getRespondWiths();
343                 for (vector<RespondWith*>::const_iterator i=src.m_RespondWiths.begin(); i!=src.m_RespondWiths.end(); i++) {
344                     if (*i) {
345                         v.push_back((*i)->cloneRespondWith());
346                     }
347                 }
348             }
349             
350             const XMLCh* getId() const {
351                 return getRequestID();
352             }
353
354             //IMPL_TYPED_CHILD(Signature);
355             // Need customized setter.
356         protected:
357             Signature* m_Signature;
358             list<XMLObject*>::iterator m_pos_Signature;
359         public:
360             Signature* getSignature() const {
361                 return m_Signature;
362             }
363             
364             void setSignature(Signature* sig) {
365                 prepareForAssignment(m_Signature,sig);
366                 *m_pos_Signature=m_Signature=sig;
367                 // Sync content reference back up.
368                 if (m_Signature)
369                     m_Signature->setContentReference(new opensaml::ContentReference(*this));
370             }
371
372             IMPL_INTEGER_ATTRIB(MinorVersion);
373             IMPL_STRING_ATTRIB(RequestID);
374             IMPL_DATETIME_ATTRIB(IssueInstant);
375             IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature);
376     
377         protected:
378             void marshallAttributes(DOMElement* domElement) const {
379                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
380                 static const XMLCh ONE[] = { chDigit_1, chNull };
381                 domElement->setAttributeNS(NULL,MAJORVERSION,ONE);
382                 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
383                 if (!m_RequestID)
384                     const_cast<AbstractRequestImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
385                 MARSHALL_ID_ATTRIB(RequestID,REQUESTID,NULL);
386                 if (!m_IssueInstant)
387                     const_cast<AbstractRequestImpl*>(this)->m_IssueInstant=new DateTime(time(NULL));
388                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
389             }
390
391             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
392                 PROC_TYPED_CHILDREN(RespondWith,SAMLConstants::SAML1P_NS,false);
393                 PROC_TYPED_CHILD(Signature,XMLConstants::XMLSIG_NS,false);
394                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
395             }
396
397             void processAttribute(const DOMAttr* attribute) {
398                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
399                 if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) {
400                     if (XMLString::parseInt(attribute->getValue()) != 1)
401                         throw UnmarshallingException("Request has invalid major version.");
402                 }
403                 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
404                 PROC_ID_ATTRIB(RequestID,REQUESTID,NULL);
405                 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
406             }
407         };
408
409         class SAML_DLLLOCAL RequestImpl : public virtual Request, public AbstractRequestImpl
410         {
411             void init() {
412                 m_children.push_back(NULL);
413                 m_Query=NULL;
414                 m_pos_Query=m_pos_Signature;
415                 ++m_pos_Query;
416             }
417         public:
418             virtual ~RequestImpl() {}
419     
420             RequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
421                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
422                 init();
423             }
424                 
425             RequestImpl(const RequestImpl& src)
426                     : AbstractXMLObject(src), AbstractRequestImpl(src) {
427                 init();
428                 if (src.getQuery())
429                     setQuery(src.getQuery()->cloneQuery());
430                 VectorOf(AssertionIDReference) v=getAssertionIDReferences();
431                 for (vector<AssertionIDReference*>::const_iterator i=src.m_AssertionIDReferences.begin(); i!=src.m_AssertionIDReferences.end(); i++) {
432                     if (*i) {
433                         v.push_back((*i)->cloneAssertionIDReference());
434                     }
435                 }
436                 VectorOf(AssertionArtifact) v2=getAssertionArtifacts();
437                 for (vector<AssertionArtifact*>::const_iterator i=src.m_AssertionArtifacts.begin(); i!=src.m_AssertionArtifacts.end(); i++) {
438                     if (*i) {
439                         v2.push_back((*i)->cloneAssertionArtifact());
440                     }
441                 }
442             }
443             
444             IMPL_XMLOBJECT_CLONE(Request);
445             AbstractRequest* cloneAbstractRequest() const {
446                 return cloneRequest();
447             }
448             IMPL_TYPED_CHILD(Query);
449             
450             SubjectQuery* getSubjectQuery() const {
451                 return dynamic_cast<SubjectQuery*>(getQuery());
452             }
453             AuthenticationQuery* getAuthenticationQuery() const {
454                 return dynamic_cast<AuthenticationQuery*>(getQuery());
455             }
456             AttributeQuery* getAttributeQuery() const {
457                 return dynamic_cast<AttributeQuery*>(getQuery());
458             }
459             AuthorizationDecisionQuery* getAuthorizationDecisionQuery() const {
460                 return dynamic_cast<AuthorizationDecisionQuery*>(getQuery());
461             }
462
463             void setSubjectQuery(SubjectQuery* q) {
464                 setQuery(q);
465             }
466             void setAuthenticationQuery(AuthenticationQuery* q) {
467                 setQuery(q);
468             }
469             void setAttributeQuery(AttributeQuery* q) {
470                 setQuery(q);
471             }
472             void setAuthorizationDecisionQuery(AuthorizationDecisionQuery* q) {
473                 setQuery(q);
474             }
475             
476             IMPL_TYPED_CHILDREN(AssertionIDReference, m_children.end());
477             IMPL_TYPED_CHILDREN(AssertionArtifact, m_children.end());
478     
479         protected:
480             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
481                 PROC_TYPED_CHILD(Query,SAMLConstants::SAML1P_NS,true);
482                 PROC_TYPED_CHILDREN(AssertionIDReference,SAMLConstants::SAML1_NS,false);
483                 PROC_TYPED_CHILDREN(AssertionArtifact,SAMLConstants::SAML1P_NS,false);
484                 AbstractRequestImpl::processChildElement(childXMLObject,root);
485             }
486         };
487
488         class SAML_DLLLOCAL StatusCodeImpl : public virtual StatusCode,
489             public AbstractComplexElement,
490             public AbstractDOMCachingXMLObject,
491             public AbstractValidatingXMLObject,
492             public AbstractXMLObjectMarshaller,
493             public AbstractXMLObjectUnmarshaller
494         {
495             void init() {
496                 m_Value=NULL;
497                 m_children.push_back(NULL);
498                 m_StatusCode=NULL;
499                 m_pos_StatusCode=m_children.begin();
500             }
501         public:
502             virtual ~StatusCodeImpl() {
503                 delete m_Value;
504             }
505     
506             StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
507                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
508                 init();
509             }
510                 
511             StatusCodeImpl(const StatusCodeImpl& src)
512                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
513                 init();
514                 setValue(src.getValue());
515                 if (src.getStatusCode())
516                     setStatusCode(src.getStatusCode()->cloneStatusCode());
517             }
518             
519             IMPL_XMLOBJECT_CLONE(StatusCode);
520             IMPL_XMLOBJECT_ATTRIB(Value,QName);
521             IMPL_TYPED_CHILD(StatusCode);
522     
523         protected:
524             void marshallAttributes(DOMElement* domElement) const {
525                 MARSHALL_QNAME_ATTRIB(Value,VALUE,NULL);
526             }
527
528             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
529                 PROC_TYPED_CHILD(StatusCode,SAMLConstants::SAML1P_NS,true);
530                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
531             }
532
533             void processAttribute(const DOMAttr* attribute) {
534                 PROC_QNAME_ATTRIB(Value,VALUE,NULL);
535             }
536         };
537
538         class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail,
539             public AbstractComplexElement,
540             public AbstractDOMCachingXMLObject,
541             public AbstractValidatingXMLObject,
542             public AbstractXMLObjectMarshaller,
543             public AbstractXMLObjectUnmarshaller
544         {
545         public:
546             virtual ~StatusDetailImpl() {}
547     
548             StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
549                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
550             }
551                 
552             StatusDetailImpl(const StatusDetailImpl& src)
553                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
554                 VectorOf(XMLObject) v=getDetails();
555                 for (vector<XMLObject*>::const_iterator i=src.m_Details.begin(); i!=src.m_Details.end(); i++) {
556                     if (*i) {
557                         v.push_back((*i)->clone());
558                     }
559                 }
560             }
561             
562             IMPL_XMLOBJECT_CLONE(StatusDetail);
563             IMPL_XMLOBJECT_CHILDREN(Detail,m_children.end());
564     
565         protected:
566             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
567                 getDetails().push_back(childXMLObject);
568             }
569         };
570
571         class SAML_DLLLOCAL StatusImpl : public virtual Status,
572             public AbstractComplexElement,
573             public AbstractDOMCachingXMLObject,
574             public AbstractValidatingXMLObject,
575             public AbstractXMLObjectMarshaller,
576             public AbstractXMLObjectUnmarshaller
577         {
578             void init() {
579                 m_children.push_back(NULL);
580                 m_children.push_back(NULL);
581                 m_children.push_back(NULL);
582                 m_StatusCode=NULL;
583                 m_pos_StatusCode=m_children.begin();
584                 m_StatusMessage=NULL;
585                 m_pos_StatusMessage=m_pos_StatusCode;
586                 ++m_pos_StatusMessage;
587                 m_StatusDetail=NULL;
588                 m_pos_StatusDetail=m_pos_StatusMessage;
589                 ++m_pos_StatusDetail;
590             }
591         public:
592             virtual ~StatusImpl() {}
593     
594             StatusImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
595                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
596                 init();
597             }
598                 
599             StatusImpl(const StatusImpl& src)
600                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
601                 init();
602                 if (src.getStatusCode())
603                     setStatusCode(src.getStatusCode()->cloneStatusCode());
604                 if (src.getStatusMessage())
605                     setStatusMessage(src.getStatusMessage()->cloneStatusMessage());
606                 if (src.getStatusDetail())
607                     setStatusDetail(src.getStatusDetail()->cloneStatusDetail());
608             }
609             
610             IMPL_XMLOBJECT_CLONE(Status);
611             IMPL_TYPED_CHILD(StatusCode);
612             IMPL_TYPED_CHILD(StatusMessage);
613             IMPL_TYPED_CHILD(StatusDetail);
614     
615         protected:
616             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
617                 PROC_TYPED_CHILD(StatusCode,SAMLConstants::SAML1P_NS,false);
618                 PROC_TYPED_CHILD(StatusMessage,SAMLConstants::SAML1P_NS,false);
619                 PROC_TYPED_CHILD(StatusDetail,SAMLConstants::SAML1P_NS,false);
620                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
621             }
622         };
623
624         class SAML_DLLLOCAL AbstractResponseImpl : public virtual AbstractResponse,
625             public AbstractComplexElement,
626             public AbstractDOMCachingXMLObject,
627             public AbstractValidatingXMLObject,
628             public AbstractXMLObjectMarshaller,
629             public AbstractXMLObjectUnmarshaller
630         {
631             void init() {
632                 m_MinorVersion=1;
633                 m_ResponseID=NULL;
634                 m_InResponseTo=NULL;
635                 m_IssueInstant=NULL;
636                 m_Recipient=NULL;
637                 m_children.push_back(NULL);
638                 m_Signature=NULL;
639                 m_pos_Signature=m_children.begin();
640             }
641         protected:
642             AbstractResponseImpl() {
643                 init();
644             }
645         public:
646             virtual ~AbstractResponseImpl() {
647                 XMLString::release(&m_ResponseID);
648                 XMLString::release(&m_InResponseTo);
649                 XMLString::release(&m_Recipient);
650                 delete m_IssueInstant;
651             }
652     
653             AbstractResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
654                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
655                 init();
656             }
657                 
658             AbstractResponseImpl(const AbstractResponseImpl& src)
659                     : AbstractXMLObject(src),
660                         AbstractDOMCachingXMLObject(src),
661                         AbstractValidatingXMLObject(src) {
662                 init();
663                 setMinorVersion(src.getMinorVersion());
664                 setResponseID(src.getResponseID());
665                 setInResponseTo(src.getInResponseTo());
666                 setIssueInstant(src.getIssueInstant());
667                 setRecipient(src.getRecipient());
668                 if (src.getSignature())
669                     setSignature(src.getSignature()->cloneSignature());
670             }
671
672             const XMLCh* getId() const {
673                 return getResponseID();
674             }
675
676             //IMPL_TYPED_CHILD(Signature);
677             // Need customized setter.
678         protected:
679             Signature* m_Signature;
680             list<XMLObject*>::iterator m_pos_Signature;
681         public:
682             Signature* getSignature() const {
683                 return m_Signature;
684             }
685             
686             void setSignature(Signature* sig) {
687                 prepareForAssignment(m_Signature,sig);
688                 *m_pos_Signature=m_Signature=sig;
689                 // Sync content reference back up.
690                 if (m_Signature)
691                     m_Signature->setContentReference(new opensaml::ContentReference(*this));
692             }
693
694             IMPL_INTEGER_ATTRIB(MinorVersion);
695             IMPL_STRING_ATTRIB(ResponseID);
696             IMPL_STRING_ATTRIB(InResponseTo);
697             IMPL_DATETIME_ATTRIB(IssueInstant);
698             IMPL_STRING_ATTRIB(Recipient);
699     
700         protected:
701             void marshallAttributes(DOMElement* domElement) const {
702                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
703                 static const XMLCh ONE[] = { chDigit_1, chNull };
704                 domElement->setAttributeNS(NULL,MAJORVERSION,ONE);
705                 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
706                 if (!m_ResponseID)
707                     const_cast<AbstractResponseImpl*>(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier();
708                 MARSHALL_ID_ATTRIB(ResponseID,RESPONSEID,NULL);
709                 MARSHALL_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL);
710                 if (!m_IssueInstant)
711                     const_cast<AbstractResponseImpl*>(this)->m_IssueInstant=new DateTime(time(NULL));
712                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
713                 MARSHALL_STRING_ATTRIB(Recipient,RECIPIENT,NULL);
714             }
715
716             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
717                 PROC_TYPED_CHILD(Signature,XMLConstants::XMLSIG_NS,false);
718                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
719             }
720
721             void processAttribute(const DOMAttr* attribute) {
722                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
723                 if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) {
724                     if (XMLString::parseInt(attribute->getValue()) != 1)
725                         throw UnmarshallingException("Response has invalid major version.");
726                 }
727                 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
728                 PROC_ID_ATTRIB(ResponseID,RESPONSEID,NULL);
729                 PROC_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL);
730                 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
731                 PROC_STRING_ATTRIB(Recipient,RECIPIENT,NULL);
732             }
733         };
734
735         class SAML_DLLLOCAL ResponseImpl : public virtual Response, public AbstractResponseImpl
736         {
737             void init() {
738                 m_children.push_back(NULL);
739                 m_Status=NULL;
740                 m_pos_Status=m_pos_Signature;
741                 ++m_pos_Status;
742             }
743         public:
744             virtual ~ResponseImpl() {}
745     
746             ResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
747                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
748                 init();
749             }
750                 
751             ResponseImpl(const ResponseImpl& src)
752                     : AbstractXMLObject(src), AbstractResponseImpl(src) {
753                 init();
754                 if (src.getStatus())
755                     setStatus(src.getStatus()->cloneStatus());
756                 VectorOf(Assertion) v=getAssertions();
757                 for (vector<Assertion*>::const_iterator i=src.m_Assertions.begin(); i!=src.m_Assertions.end(); i++) {
758                     if (*i) {
759                         v.push_back((*i)->cloneAssertion());
760                     }
761                 }
762             }
763             
764             IMPL_XMLOBJECT_CLONE(Response);
765             AbstractResponse* cloneAbstractResponse() const {
766                 return cloneResponse();
767             }
768             IMPL_TYPED_CHILD(Status);
769             IMPL_TYPED_CHILDREN(Assertion, m_children.end());
770     
771         protected:
772             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
773                 PROC_TYPED_CHILD(Status,SAMLConstants::SAML1P_NS,false);
774                 PROC_TYPED_CHILDREN(Assertion,SAMLConstants::SAML1_NS,true);
775                 AbstractResponseImpl::processChildElement(childXMLObject,root);
776             }
777         };
778
779     };
780 };
781
782 #if defined (_MSC_VER)
783     #pragma warning( pop )
784 #endif
785
786 // Builder Implementations
787
788 IMPL_XMLOBJECTBUILDER(AssertionArtifact);
789 IMPL_XMLOBJECTBUILDER(AttributeQuery);
790 IMPL_XMLOBJECTBUILDER(AuthenticationQuery);
791 IMPL_XMLOBJECTBUILDER(AuthorizationDecisionQuery);
792 IMPL_XMLOBJECTBUILDER(Request);
793 IMPL_XMLOBJECTBUILDER(RespondWith);
794 IMPL_XMLOBJECTBUILDER(Response);
795 IMPL_XMLOBJECTBUILDER(Status);
796 IMPL_XMLOBJECTBUILDER(StatusCode);
797 IMPL_XMLOBJECTBUILDER(StatusDetail);
798 IMPL_XMLOBJECTBUILDER(StatusMessage);
799
800 // Unicode literals
801 const XMLCh AbstractRequest::MINORVERSION_ATTRIB_NAME[] =   UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
802 const XMLCh AbstractRequest::REQUESTID_ATTRIB_NAME[] =      UNICODE_LITERAL_9(R,e,q,u,e,s,t,I,D);
803 const XMLCh AbstractRequest::ISSUEINSTANT_ATTRIB_NAME[] =   UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
804 const XMLCh AbstractResponse::MINORVERSION_ATTRIB_NAME[] =  UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
805 const XMLCh AbstractResponse::RESPONSEID_ATTRIB_NAME[] =    UNICODE_LITERAL_10(R,e,s,p,o,n,s,e,I,D);
806 const XMLCh AbstractResponse::ISSUEINSTANT_ATTRIB_NAME[] =  UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
807 const XMLCh AbstractResponse::INRESPONSETO_ATTRIB_NAME[] =  UNICODE_LITERAL_12(I,n,R,e,s,p,o,n,s,e,T,o);
808 const XMLCh AbstractResponse::RECIPIENT_ATTRIB_NAME[] =     UNICODE_LITERAL_9(R,e,c,i,p,i,e,n,t);
809 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);
810 const XMLCh AttributeQuery::LOCAL_NAME[] =                  UNICODE_LITERAL_14(A,t,t,r,i,b,u,t,e,Q,u,e,r,y);
811 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);
812 const XMLCh AttributeQuery::RESOURCE_ATTRIB_NAME[] =        UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
813 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);
814 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);
815 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);
816 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);
817 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);
818 const XMLCh AuthorizationDecisionQuery::RESOURCE_ATTRIB_NAME[] =        UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
819 const XMLCh Query::LOCAL_NAME[] =                           UNICODE_LITERAL_5(Q,u,e,r,y);
820 const XMLCh Request::LOCAL_NAME[] =                         UNICODE_LITERAL_7(R,e,q,u,e,s,t);
821 const XMLCh Request::TYPE_NAME[] =                          UNICODE_LITERAL_11(R,e,q,u,e,s,t,T,y,p,e);
822 const XMLCh RespondWith::LOCAL_NAME[] =                     UNICODE_LITERAL_11(R,e,s,p,o,n,d,W,i,t,h);
823 const XMLCh Response::LOCAL_NAME[] =                        UNICODE_LITERAL_8(R,e,s,p,o,n,s,e);
824 const XMLCh Response::TYPE_NAME[] =                         UNICODE_LITERAL_12(R,e,s,p,o,n,s,e,T,y,p,e);
825 const XMLCh Status::LOCAL_NAME[] =                          UNICODE_LITERAL_6(S,t,a,t,u,s);
826 const XMLCh Status::TYPE_NAME[] =                           UNICODE_LITERAL_10(S,t,a,t,u,s,T,y,p,e);
827 const XMLCh StatusCode::LOCAL_NAME[] =                      UNICODE_LITERAL_10(S,t,a,t,u,s,C,o,d,e);
828 const XMLCh StatusCode::TYPE_NAME[] =                       UNICODE_LITERAL_14(S,t,a,t,u,s,C,o,d,e,T,y,p,e);
829 const XMLCh StatusCode::VALUE_ATTRIB_NAME[] =               UNICODE_LITERAL_5(V,a,l,u,e);
830 const XMLCh StatusDetail::LOCAL_NAME[] =                    UNICODE_LITERAL_12(S,t,a,t,u,s,D,e,t,a,i,l);
831 const XMLCh StatusDetail::TYPE_NAME[] =                     UNICODE_LITERAL_16(S,t,a,t,u,s,D,e,t,a,i,l,T,y,p,e);
832 const XMLCh StatusMessage::LOCAL_NAME[] =                   UNICODE_LITERAL_13(S,t,a,t,u,s,M,e,s,s,a,g,e);
833 const XMLCh SubjectQuery::LOCAL_NAME[] =                    UNICODE_LITERAL_12(S,u,b,j,e,c,t,Q,u,e,r,y);
834
835 #define XCH(ch) chLatin_##ch
836 #define XNUM(d) chDigit_##d
837
838 const XMLCh _SUCCESS[] =                                    UNICODE_LITERAL_7(S,u,c,c,e,s,s);
839 const XMLCh _REQUESTER[] =                                  UNICODE_LITERAL_9(R,e,q,u,e,s,t,e,r);
840 const XMLCh _RESPONDER[] =                                  UNICODE_LITERAL_9(R,e,s,p,o,n,d,e,r);
841 const XMLCh _VERSIONMISMATCH[] =                            UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h);
842  
843 QName StatusCode::SUCCESS(SAMLConstants::SAML1P_NS,_SUCCESS,SAMLConstants::SAML1P_PREFIX);
844 QName StatusCode::REQUESTER(SAMLConstants::SAML1P_NS,_REQUESTER,SAMLConstants::SAML1P_PREFIX);
845 QName StatusCode::RESPONDER(SAMLConstants::SAML1P_NS,_RESPONDER,SAMLConstants::SAML1P_PREFIX);
846 QName StatusCode::VERSIONMISMATCH(SAMLConstants::SAML1P_NS,_VERSIONMISMATCH,SAMLConstants::SAML1P_PREFIX);