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