Line data Source code
1 : /**
2 : * XML Security Library (http://www.aleksey.com/xmlsec).
3 : *
4 : * Simple SOAP messages parsing/creation.
5 : *
6 : * This is free software; see Copyright file in the source
7 : * distribution for preciese wording.
8 : *
9 : * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
10 : */
11 : #include "globals.h"
12 :
13 : #ifndef XMLSEC_NO_SOAP
14 :
15 : #include <stdlib.h>
16 : #include <string.h>
17 :
18 : #include <libxml/tree.h>
19 :
20 : #include <xmlsec/xmlsec.h>
21 : #include <xmlsec/xmltree.h>
22 : #include <xmlsec/soap.h>
23 : #include <xmlsec/errors.h>
24 :
25 : /***********************************************************************
26 : *
27 : * SOAP 1.1
28 : *
29 : **********************************************************************/
30 : /**
31 : * xmlSecSoap11CreateEnvelope:
32 : * @doc: the parent doc (might be NULL).
33 : *
34 : * Creates a new SOAP Envelope node. Caller is responsible for
35 : * adding the returned node to the XML document.
36 : *
37 : * XML Schema (http://schemas.xmlsoap.org/soap/envelope/):
38 : *
39 : * <xs:element name="Envelope" type="tns:Envelope"/>
40 : * <xs:complexType name="Envelope">
41 : * <xs:sequence>
42 : * <xs:element ref="tns:Header" minOccurs="0"/>
43 : * <xs:element ref="tns:Body" minOccurs="1"/>
44 : * <xs:any namespace="##other" minOccurs="0"
45 : * maxOccurs="unbounded" processContents="lax"/>
46 : * </xs:sequence>
47 : * <xs:anyAttribute namespace="##other" processContents="lax"/>
48 : * </xs:complexType>
49 : *
50 : * Returns: pointer to newly created <soap:Envelope> node or NULL
51 : * if an error occurs.
52 : */
53 : xmlNodePtr
54 0 : xmlSecSoap11CreateEnvelope(xmlDocPtr doc) {
55 : xmlNodePtr envNode;
56 : xmlNodePtr bodyNode;
57 : xmlNsPtr ns;
58 :
59 : /* create Envelope node */
60 0 : envNode = xmlNewDocNode(doc, NULL, xmlSecNodeEnvelope, NULL);
61 0 : if(envNode == NULL) {
62 0 : xmlSecError(XMLSEC_ERRORS_HERE,
63 : NULL,
64 : "xmlNewDocNode",
65 : XMLSEC_ERRORS_R_XML_FAILED,
66 : "node=%s",
67 : xmlSecErrorsSafeString(xmlSecNodeEnvelope));
68 0 : return(NULL);
69 : }
70 :
71 0 : ns = xmlNewNs(envNode, xmlSecSoap11Ns, NULL) ;
72 0 : if(ns == NULL) {
73 0 : xmlSecError(XMLSEC_ERRORS_HERE,
74 : NULL,
75 : "xmlNewNs",
76 : XMLSEC_ERRORS_R_XML_FAILED,
77 : "ns=%s",
78 : xmlSecErrorsSafeString(xmlSecSoap11Ns));
79 0 : xmlFreeNode(envNode);
80 0 : return(NULL);
81 : }
82 0 : xmlSetNs(envNode, ns);
83 :
84 : /* add required Body node */
85 0 : bodyNode = xmlSecAddChild(envNode, xmlSecNodeBody, xmlSecSoap11Ns);
86 0 : if(bodyNode == NULL) {
87 0 : xmlSecError(XMLSEC_ERRORS_HERE,
88 : NULL,
89 : "xmlSecAddChild",
90 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
91 : "node=%s",
92 : xmlSecErrorsSafeString(xmlSecNodeBody));
93 0 : xmlFreeNode(envNode);
94 0 : return(NULL);
95 : }
96 :
97 0 : return(envNode);
98 : }
99 :
100 : /**
101 : * xmlSecSoap11EnsureHeader:
102 : * @envNode: the pointer to <soap:Envelope> node.
103 : *
104 : * Gets the pointer to <soap:Header> node (if necessary, the node
105 : * is created).
106 : *
107 : * XML Schema (http://schemas.xmlsoap.org/soap/envelope/):
108 : *
109 : * <xs:element name="Header" type="tns:Header"/>
110 : * <xs:complexType name="Header">
111 : * <xs:sequence>
112 : * <xs:any namespace="##other" minOccurs="0"
113 : * maxOccurs="unbounded" processContents="lax"/>
114 : * </xs:sequence>
115 : * <xs:anyAttribute namespace="##other" processContents="lax"/>
116 : * </xs:complexType>
117 : *
118 : * Returns: pointer to <soap:Header> node or NULL if an error occurs.
119 : */
120 : xmlNodePtr
121 0 : xmlSecSoap11EnsureHeader(xmlNodePtr envNode) {
122 : xmlNodePtr hdrNode;
123 : xmlNodePtr cur;
124 :
125 0 : xmlSecAssert2(envNode != NULL, NULL);
126 :
127 : /* try to find Header node first */
128 0 : cur = xmlSecGetNextElementNode(envNode->children);
129 0 : if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHeader, xmlSecSoap11Ns)) {
130 0 : return(cur);
131 : }
132 :
133 : /* if the first element child is not Header then it is Body */
134 0 : if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeBody, xmlSecSoap11Ns)) {
135 0 : xmlSecError(XMLSEC_ERRORS_HERE,
136 : NULL,
137 : xmlSecErrorsSafeString(xmlSecNodeBody),
138 : XMLSEC_ERRORS_R_NODE_NOT_FOUND,
139 : XMLSEC_ERRORS_NO_MESSAGE);
140 0 : return(NULL);
141 : }
142 :
143 : /* finally add Header node before body */
144 0 : hdrNode = xmlSecAddPrevSibling(cur, xmlSecNodeHeader, xmlSecSoap11Ns);
145 0 : if(hdrNode == NULL) {
146 0 : xmlSecError(XMLSEC_ERRORS_HERE,
147 : NULL,
148 : "xmlSecAddPrevSibling",
149 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
150 : XMLSEC_ERRORS_NO_MESSAGE);
151 0 : return(NULL);
152 : }
153 :
154 0 : return(hdrNode);
155 : }
156 :
157 : /**
158 : * xmlSecSoap11AddBodyEntry:
159 : * @envNode: the pointer to <soap:Envelope> node.
160 : * @entryNode: the pointer to body entry node.
161 : *
162 : * Adds a new entry to <soap:Body> node.
163 : *
164 : * Returns: pointer to the added entry (@contentNode) or NULL if an error occurs.
165 : */
166 : xmlNodePtr
167 0 : xmlSecSoap11AddBodyEntry(xmlNodePtr envNode, xmlNodePtr entryNode) {
168 : xmlNodePtr bodyNode;
169 :
170 0 : xmlSecAssert2(envNode != NULL, NULL);
171 0 : xmlSecAssert2(entryNode != NULL, NULL);
172 :
173 0 : bodyNode = xmlSecSoap11GetBody(envNode);
174 0 : if(bodyNode == NULL) {
175 0 : xmlSecError(XMLSEC_ERRORS_HERE,
176 : NULL,
177 : "xmlSecSoap11GetBody",
178 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
179 : XMLSEC_ERRORS_NO_MESSAGE);
180 0 : return(NULL);
181 : }
182 :
183 0 : return(xmlSecAddChildNode(bodyNode, entryNode));
184 : }
185 :
186 : /**
187 : * xmlSecSoap11AddFaultEntry:
188 : * @envNode: the pointer to <soap:Envelope> node.
189 : * @faultCodeHref: the fault code QName href (must be known in th context of
190 : * <soap:Body> node).
191 : * @faultCodeLocalPart: the fault code QName LocalPart.
192 : * @faultString: the human readable explanation of the fault.
193 : * @faultActor: the information about who caused the fault (might be NULL).
194 : *
195 : * Adds <soap:Fault> entry to the @envNode. Note that only one <soap:Fault>
196 : * entry is allowed.
197 : *
198 : * XML Schema (http://schemas.xmlsoap.org/soap/envelope/):
199 : *
200 : * <xs:element name="Fault" type="tns:Fault"/>
201 : * <xs:complexType name="Fault" final="extension">
202 : * <xs:sequence>
203 : * <xs:element name="faultcode" type="xs:QName"/>
204 : * <xs:element name="faultstring" type="xs:string"/>
205 : * <xs:element name="faultactor" type="xs:anyURI" minOccurs="0"/>
206 : * <xs:element name="detail" type="tns:detail" minOccurs="0"/>
207 : * </xs:sequence>
208 : * </xs:complexType>
209 : * <xs:complexType name="detail">
210 : * <xs:sequence>
211 : * <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded"
212 : * processContents="lax"/>
213 : * </xs:sequence>
214 : * <xs:anyAttribute namespace="##any" processContents="lax"/>
215 : * </xs:complexType>
216 : *
217 : * Returns: pointer to the added entry or NULL if an error occurs.
218 : */
219 : xmlNodePtr
220 0 : xmlSecSoap11AddFaultEntry(xmlNodePtr envNode, const xmlChar* faultCodeHref,
221 : const xmlChar* faultCodeLocalPart,
222 : const xmlChar* faultString, const xmlChar* faultActor) {
223 : xmlNodePtr bodyNode;
224 : xmlNodePtr faultNode;
225 : xmlNodePtr cur;
226 : xmlChar* qname;
227 :
228 0 : xmlSecAssert2(envNode != NULL, NULL);
229 0 : xmlSecAssert2(faultCodeLocalPart != NULL, NULL);
230 0 : xmlSecAssert2(faultString != NULL, NULL);
231 :
232 : /* get Body node */
233 0 : bodyNode = xmlSecSoap11GetBody(envNode);
234 0 : if(bodyNode == NULL) {
235 0 : xmlSecError(XMLSEC_ERRORS_HERE,
236 : NULL,
237 : "xmlSecSoap11GetBody",
238 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
239 : XMLSEC_ERRORS_NO_MESSAGE);
240 0 : return(NULL);
241 : }
242 :
243 : /* check that we don't have Fault node already */
244 0 : faultNode = xmlSecFindChild(bodyNode, xmlSecNodeFault, xmlSecSoap11Ns);
245 0 : if(faultNode != NULL) {
246 0 : xmlSecError(XMLSEC_ERRORS_HERE,
247 : NULL,
248 : xmlSecErrorsSafeString(xmlSecNodeBody),
249 : XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
250 : XMLSEC_ERRORS_NO_MESSAGE);
251 0 : return(NULL);
252 : }
253 :
254 : /* add Fault node */
255 0 : faultNode = xmlSecAddChild(bodyNode, xmlSecNodeFault, xmlSecSoap11Ns);
256 0 : if(faultNode == NULL) {
257 0 : xmlSecError(XMLSEC_ERRORS_HERE,
258 : NULL,
259 : "xmlSecAddChild",
260 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
261 : "node=%s",
262 : xmlSecErrorsSafeString(xmlSecNodeFault));
263 0 : return(NULL);
264 : }
265 :
266 : /* add faultcode node */
267 0 : cur = xmlSecAddChild(faultNode, xmlSecNodeFaultCode, xmlSecSoap11Ns);
268 0 : if(cur == NULL) {
269 0 : xmlSecError(XMLSEC_ERRORS_HERE,
270 : NULL,
271 : "xmlSecAddChild",
272 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
273 : "node=%s",
274 : xmlSecErrorsSafeString(xmlSecNodeFaultCode));
275 0 : xmlUnlinkNode(faultNode);
276 0 : xmlFreeNode(faultNode);
277 0 : return(NULL);
278 : }
279 :
280 : /* create qname for fault code */
281 0 : qname = xmlSecGetQName(cur, faultCodeHref, faultCodeLocalPart);
282 0 : if(qname == NULL) {
283 0 : xmlSecError(XMLSEC_ERRORS_HERE,
284 : NULL,
285 : "xmlSecGetQName",
286 : XMLSEC_ERRORS_R_XML_FAILED,
287 : "node=%s",
288 0 : xmlSecErrorsSafeString(cur->name));
289 0 : xmlUnlinkNode(faultNode);
290 0 : xmlFreeNode(faultNode);
291 0 : return(NULL);
292 : }
293 :
294 : /* set faultcode value */
295 0 : xmlNodeSetContent(cur, qname);
296 0 : xmlFree(qname);
297 :
298 : /* add faultstring node */
299 0 : cur = xmlSecAddChild(faultNode, xmlSecNodeFaultString, xmlSecSoap11Ns);
300 0 : if(cur == NULL) {
301 0 : xmlSecError(XMLSEC_ERRORS_HERE,
302 : NULL,
303 : "xmlSecAddChild",
304 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
305 : "node=%s",
306 : xmlSecErrorsSafeString(xmlSecNodeFaultString));
307 0 : xmlUnlinkNode(faultNode);
308 0 : xmlFreeNode(faultNode);
309 0 : return(NULL);
310 : }
311 :
312 : /* set faultstring node */
313 0 : xmlNodeSetContent(cur, faultString);
314 :
315 0 : if(faultActor != NULL) {
316 : /* add faultactor node */
317 0 : cur = xmlSecAddChild(faultNode, xmlSecNodeFaultActor, xmlSecSoap11Ns);
318 0 : if(cur == NULL) {
319 0 : xmlSecError(XMLSEC_ERRORS_HERE,
320 : NULL,
321 : "xmlSecAddChild",
322 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
323 : "node=%s",
324 : xmlSecErrorsSafeString(xmlSecNodeFaultActor));
325 0 : xmlUnlinkNode(faultNode);
326 0 : xmlFreeNode(faultNode);
327 0 : return(NULL);
328 : }
329 :
330 : /* set faultactor node */
331 0 : xmlNodeSetContent(cur, faultActor);
332 : }
333 :
334 0 : return(faultNode);
335 : }
336 :
337 : /**
338 : * xmlSecSoap11CheckEnvelope:
339 : * @envNode: the pointer to <soap:Envelope> node.
340 : *
341 : * Validates <soap:Envelope> node structure.
342 : *
343 : * Returns: 1 if @envNode has a valid <soap:Envelope> element, 0 if it is
344 : * not valid or a negative value if an error occurs.
345 : */
346 : int
347 0 : xmlSecSoap11CheckEnvelope(xmlNodePtr envNode) {
348 : xmlNodePtr cur;
349 :
350 0 : xmlSecAssert2(envNode != NULL, -1);
351 :
352 : /* verify envNode itself */
353 0 : if(!xmlSecCheckNodeName(envNode, xmlSecNodeEnvelope, xmlSecSoap11Ns)) {
354 0 : xmlSecError(XMLSEC_ERRORS_HERE,
355 : NULL,
356 : xmlSecErrorsSafeString(xmlSecNodeEnvelope),
357 : XMLSEC_ERRORS_R_NODE_NOT_FOUND,
358 : XMLSEC_ERRORS_NO_MESSAGE);
359 0 : return(0);
360 : }
361 :
362 : /* optional Header node first */
363 0 : cur = xmlSecGetNextElementNode(envNode->children);
364 0 : if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHeader, xmlSecSoap11Ns)) {
365 0 : cur = xmlSecGetNextElementNode(cur->next);
366 : }
367 :
368 : /* required Body node is next */
369 0 : if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeBody, xmlSecSoap11Ns)) {
370 0 : xmlSecError(XMLSEC_ERRORS_HERE,
371 : NULL,
372 : xmlSecErrorsSafeString(xmlSecNodeBody),
373 : XMLSEC_ERRORS_R_NODE_NOT_FOUND,
374 : XMLSEC_ERRORS_NO_MESSAGE);
375 0 : return(0);
376 : }
377 :
378 0 : return(1);
379 : }
380 :
381 : /**
382 : * xmlSecSoap11GetHeader:
383 : * @envNode: the pointer to <soap:Envelope> node.
384 : *
385 : * Gets pointer to the <soap:Header> node.
386 : *
387 : * Returns: pointer to <soap:Header> node or NULL if an error occurs.
388 : */
389 : xmlNodePtr
390 0 : xmlSecSoap11GetHeader(xmlNodePtr envNode) {
391 : xmlNodePtr cur;
392 :
393 0 : xmlSecAssert2(envNode != NULL, NULL);
394 :
395 : /* optional Header node is first */
396 0 : cur = xmlSecGetNextElementNode(envNode->children);
397 0 : if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHeader, xmlSecSoap11Ns)) {
398 0 : return(cur);
399 : }
400 :
401 0 : return(NULL);
402 : }
403 :
404 : /**
405 : * xmlSecSoap11GetBody:
406 : * @envNode: the pointer to <soap:Envelope> node.
407 : *
408 : * Gets pointer to the <soap:Body> node.
409 : *
410 : * Returns: pointer to <soap:Body> node or NULL if an error occurs.
411 : */
412 : xmlNodePtr
413 0 : xmlSecSoap11GetBody(xmlNodePtr envNode) {
414 : xmlNodePtr cur;
415 :
416 0 : xmlSecAssert2(envNode != NULL, NULL);
417 :
418 : /* optional Header node first */
419 0 : cur = xmlSecGetNextElementNode(envNode->children);
420 0 : if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHeader, xmlSecSoap11Ns)) {
421 0 : cur = xmlSecGetNextElementNode(cur->next);
422 : }
423 :
424 : /* Body node is next */
425 0 : if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeBody, xmlSecSoap11Ns)) {
426 0 : xmlSecError(XMLSEC_ERRORS_HERE,
427 : NULL,
428 : xmlSecErrorsSafeString(xmlSecNodeBody),
429 : XMLSEC_ERRORS_R_NODE_NOT_FOUND,
430 : XMLSEC_ERRORS_NO_MESSAGE);
431 0 : return(NULL);
432 : }
433 :
434 0 : return(cur);
435 : }
436 :
437 : /**
438 : * xmlSecSoap11GetBodyEntriesNumber:
439 : * @envNode: the pointer to <soap:Envelope> node.
440 : *
441 : * Gets the number of body entries.
442 : *
443 : * Returns: the number of body entries.
444 : */
445 : xmlSecSize
446 0 : xmlSecSoap11GetBodyEntriesNumber(xmlNodePtr envNode) {
447 0 : xmlSecSize number = 0;
448 : xmlNodePtr bodyNode;
449 : xmlNodePtr cur;
450 :
451 0 : xmlSecAssert2(envNode != NULL, 0);
452 :
453 : /* get Body node */
454 0 : bodyNode = xmlSecSoap11GetBody(envNode);
455 0 : if(bodyNode == NULL) {
456 0 : xmlSecError(XMLSEC_ERRORS_HERE,
457 : NULL,
458 : "xmlSecSoap11GetBody",
459 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
460 : XMLSEC_ERRORS_NO_MESSAGE);
461 0 : return(0);
462 : }
463 :
464 0 : cur = xmlSecGetNextElementNode(bodyNode->children);
465 0 : while(cur != NULL) {
466 0 : number++;
467 0 : cur = xmlSecGetNextElementNode(cur->next);
468 : }
469 :
470 0 : return(number);
471 : }
472 :
473 : /**
474 : * xmlSecSoap11GetBodyEntry:
475 : * @envNode: the pointer to <soap:Envelope> node.
476 : * @pos: the body entry number.
477 : *
478 : * Gets the body entry number @pos.
479 : *
480 : * Returns: pointer to body entry node or NULL if an error occurs.
481 : */
482 : xmlNodePtr
483 0 : xmlSecSoap11GetBodyEntry(xmlNodePtr envNode, xmlSecSize pos) {
484 : xmlNodePtr bodyNode;
485 : xmlNodePtr cur;
486 :
487 0 : xmlSecAssert2(envNode != NULL, NULL);
488 :
489 : /* get Body node */
490 0 : bodyNode = xmlSecSoap11GetBody(envNode);
491 0 : if(bodyNode == NULL) {
492 0 : xmlSecError(XMLSEC_ERRORS_HERE,
493 : NULL,
494 : "xmlSecSoap11GetBody",
495 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
496 : XMLSEC_ERRORS_NO_MESSAGE);
497 0 : return(NULL);
498 : }
499 :
500 0 : cur = xmlSecGetNextElementNode(bodyNode->children);
501 0 : while((cur != NULL) && (pos > 0)) {
502 0 : pos--;
503 0 : cur = xmlSecGetNextElementNode(cur->next);
504 : }
505 :
506 0 : return(cur);
507 : }
508 :
509 : /**
510 : * xmlSecSoap11GetFaultEntry:
511 : * @envNode: the pointer to <soap:Envelope> node.
512 : *
513 : * Gets the Fault entry (if any).
514 : *
515 : * Returns: pointer to Fault entry or NULL if it does not exist.
516 : */
517 : xmlNodePtr
518 0 : xmlSecSoap11GetFaultEntry(xmlNodePtr envNode) {
519 : xmlNodePtr bodyNode;
520 :
521 0 : xmlSecAssert2(envNode != NULL, NULL);
522 :
523 : /* get Body node */
524 0 : bodyNode = xmlSecSoap11GetBody(envNode);
525 0 : if(bodyNode == NULL) {
526 0 : xmlSecError(XMLSEC_ERRORS_HERE,
527 : NULL,
528 : "xmlSecSoap11GetBody",
529 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
530 : XMLSEC_ERRORS_NO_MESSAGE);
531 0 : return(NULL);
532 : }
533 :
534 0 : return(xmlSecFindChild(bodyNode, xmlSecNodeFault, xmlSecSoap11Ns));
535 : }
536 :
537 :
538 : /***********************************************************************
539 : *
540 : * SOAP 1.2
541 : *
542 : **********************************************************************/
543 : static const xmlSecQName2IntegerInfo gXmlSecSoap12FaultCodeInfo[] =
544 : {
545 : { xmlSecSoap12Ns, xmlSecSoapFaultCodeVersionMismatch,
546 : xmlSecSoap12FaultCodeVersionMismatch },
547 : { xmlSecSoap12Ns, xmlSecSoapFaultCodeMustUnderstand,
548 : xmlSecSoap12FaultCodeMustUnderstand },
549 : { xmlSecSoap12Ns, xmlSecSoapFaultDataEncodningUnknown,
550 : xmlSecSoap12FaultCodeDataEncodingUnknown },
551 : { xmlSecSoap12Ns, xmlSecSoapFaultCodeSender,
552 : xmlSecSoap12FaultCodeSender },
553 : { xmlSecSoap12Ns, xmlSecSoapFaultCodeReceiver,
554 : xmlSecSoap12FaultCodeReceiver },
555 : { NULL, NULL, 0 } /* MUST be last in the list */
556 : };
557 :
558 : /**
559 : * xmlSecSoap12CreateEnvelope:
560 : * @doc: the parent doc (might be NULL).
561 : *
562 : * Creates a new SOAP 1.2 Envelope node. Caller is responsible for
563 : * adding the returned node to the XML document.
564 : *
565 : * XML Schema (http://www.w3.org/2003/05/soap-envelope):
566 : *
567 : * <xs:element name="Envelope" type="tns:Envelope"/>
568 : * <xs:complexType name="Envelope">
569 : * <xs:sequence>
570 : * <xs:element ref="tns:Header" minOccurs="0"/>
571 : * <xs:element ref="tns:Body" minOccurs="1"/>
572 : * </xs:sequence>
573 : * <xs:anyAttribute namespace="##other" processContents="lax"/>
574 : * </xs:complexType>
575 : *
576 : * Returns: pointer to newly created <soap:Envelope> node or NULL
577 : * if an error occurs.
578 : */
579 : xmlNodePtr
580 0 : xmlSecSoap12CreateEnvelope(xmlDocPtr doc) {
581 : xmlNodePtr envNode;
582 : xmlNodePtr bodyNode;
583 : xmlNsPtr ns;
584 :
585 : /* create Envelope node */
586 0 : envNode = xmlNewDocNode(doc, NULL, xmlSecNodeEnvelope, NULL);
587 0 : if(envNode == NULL) {
588 0 : xmlSecError(XMLSEC_ERRORS_HERE,
589 : NULL,
590 : "xmlNewDocNode",
591 : XMLSEC_ERRORS_R_XML_FAILED,
592 : "node=%s",
593 : xmlSecErrorsSafeString(xmlSecNodeEnvelope));
594 0 : return(NULL);
595 : }
596 :
597 0 : ns = xmlNewNs(envNode, xmlSecSoap12Ns, NULL) ;
598 0 : if(ns == NULL) {
599 0 : xmlSecError(XMLSEC_ERRORS_HERE,
600 : NULL,
601 : "xmlNewNs",
602 : XMLSEC_ERRORS_R_XML_FAILED,
603 : "ns=%s",
604 : xmlSecErrorsSafeString(xmlSecSoap12Ns));
605 0 : xmlFreeNode(envNode);
606 0 : return(NULL);
607 : }
608 0 : xmlSetNs(envNode, ns);
609 :
610 : /* add required Body node */
611 0 : bodyNode = xmlSecAddChild(envNode, xmlSecNodeBody, xmlSecSoap12Ns);
612 0 : if(bodyNode == NULL) {
613 0 : xmlSecError(XMLSEC_ERRORS_HERE,
614 : NULL,
615 : "xmlSecAddChild",
616 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
617 : "node=%s",
618 : xmlSecErrorsSafeString(xmlSecNodeBody));
619 0 : xmlFreeNode(envNode);
620 0 : return(NULL);
621 : }
622 :
623 0 : return(envNode);
624 : }
625 :
626 : /**
627 : * xmlSecSoap12EnsureHeader:
628 : * @envNode: the pointer to <soap:Envelope> node.
629 : *
630 : * Gets the pointer to <soap:Header> node (if necessary, the node
631 : * is created).
632 : *
633 : * XML Schema (http://www.w3.org/2003/05/soap-envelope):
634 : *
635 : * <xs:element name="Header" type="tns:Header"/>
636 : * <xs:complexType name="Header">
637 : * <xs:sequence>
638 : * <xs:any namespace="##any" processContents="lax"
639 : * minOccurs="0" maxOccurs="unbounded"/>
640 : * </xs:sequence>
641 : * <xs:anyAttribute namespace="##other" processContents="lax"/>
642 : * </xs:complexType>
643 : *
644 : * Returns: pointer to <soap:Header> node or NULL if an error occurs.
645 : */
646 : xmlNodePtr
647 0 : xmlSecSoap12EnsureHeader(xmlNodePtr envNode) {
648 : xmlNodePtr hdrNode;
649 : xmlNodePtr cur;
650 :
651 0 : xmlSecAssert2(envNode != NULL, NULL);
652 :
653 : /* try to find Header node first */
654 0 : cur = xmlSecGetNextElementNode(envNode->children);
655 0 : if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHeader, xmlSecSoap12Ns)) {
656 0 : return(cur);
657 : }
658 :
659 : /* if the first element child is not Header then it is Body */
660 0 : if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeBody, xmlSecSoap12Ns)) {
661 0 : xmlSecError(XMLSEC_ERRORS_HERE,
662 : NULL,
663 : xmlSecErrorsSafeString(xmlSecNodeBody),
664 : XMLSEC_ERRORS_R_NODE_NOT_FOUND,
665 : XMLSEC_ERRORS_NO_MESSAGE);
666 0 : return(NULL);
667 : }
668 :
669 : /* finally add Header node before body */
670 0 : hdrNode = xmlSecAddPrevSibling(cur, xmlSecNodeHeader, xmlSecSoap12Ns);
671 0 : if(hdrNode == NULL) {
672 0 : xmlSecError(XMLSEC_ERRORS_HERE,
673 : NULL,
674 : "xmlSecAddPrevSibling",
675 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
676 : XMLSEC_ERRORS_NO_MESSAGE);
677 0 : return(NULL);
678 : }
679 :
680 0 : return(hdrNode);
681 : }
682 :
683 : /**
684 : * xmlSecSoap12AddBodyEntry:
685 : * @envNode: the pointer to <soap:Envelope> node.
686 : * @entryNode: the pointer to body entry node.
687 : *
688 : * Adds a new entry to <soap:Body> node.
689 : *
690 : * XML Schema (http://www.w3.org/2003/05/soap-envelope):
691 : *
692 : * <xs:element name="Body" type="tns:Body"/>
693 : * <xs:complexType name="Body">
694 : * <xs:sequence>
695 : * <xs:any namespace="##any" processContents="lax"
696 : * minOccurs="0" maxOccurs="unbounded"/>
697 : * </xs:sequence>
698 : * <xs:anyAttribute namespace="##other" processContents="lax"/>
699 : * </xs:complexType>
700 : *
701 : * Returns: pointer to the added entry (@contentNode) or NULL if an error occurs.
702 : */
703 : xmlNodePtr
704 0 : xmlSecSoap12AddBodyEntry(xmlNodePtr envNode, xmlNodePtr entryNode) {
705 : xmlNodePtr bodyNode;
706 :
707 0 : xmlSecAssert2(envNode != NULL, NULL);
708 0 : xmlSecAssert2(entryNode != NULL, NULL);
709 :
710 0 : bodyNode = xmlSecSoap12GetBody(envNode);
711 0 : if(bodyNode == NULL) {
712 0 : xmlSecError(XMLSEC_ERRORS_HERE,
713 : NULL,
714 : "xmlSecSoap12GetBody",
715 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
716 : XMLSEC_ERRORS_NO_MESSAGE);
717 0 : return(NULL);
718 : }
719 :
720 0 : return(xmlSecAddChildNode(bodyNode, entryNode));
721 : }
722 :
723 : /**
724 : * xmlSecSoap12AddFaultEntry:
725 : * @envNode: the pointer to <soap:Envelope> node.
726 : * @faultCode: the fault code.
727 : * @faultReasonText: the human readable explanation of the fault.
728 : * @faultReasonLang: the language (xml:lang) for @faultReason string.
729 : * @faultNodeURI: the more preciese information about fault source
730 : * (might be NULL).
731 : * @faultRole: the role the node was operating in at the point
732 : * the fault occurred (might be NULL).
733 : *
734 : * Adds <soap:Fault> entry to the @envNode. Note that only one <soap:Fault>
735 : * entry is allowed.
736 : *
737 : * XML Schema (http://www.w3.org/2003/05/soap-envelope):
738 : *
739 : * <xs:element name="Fault" type="tns:Fault"/>
740 : * <xs:complexType name="Fault" final="extension">
741 : * <xs:sequence>
742 : * <xs:element name="Code" type="tns:faultcode"/>
743 : * <xs:element name="Reason" type="tns:faultreason"/>
744 : * <xs:element name="Node" type="xs:anyURI" minOccurs="0"/>
745 : * <xs:element name="Role" type="xs:anyURI" minOccurs="0"/>
746 : * <xs:element name="Detail" type="tns:detail" minOccurs="0"/>
747 : * </xs:sequence>
748 : * </xs:complexType>
749 : *
750 : * <xs:complexType name="faultcode">
751 : * <xs:sequence>
752 : * <xs:element name="Value" type="tns:faultcodeEnum"/>
753 : * <xs:element name="Subcode" type="tns:subcode" minOccurs="0"/>
754 : * </xs:sequence>
755 : * </xs:complexType>
756 : *
757 : * <xs:complexType name="faultreason">
758 : * <xs:sequence>
759 : * <xs:element name="Text" type="tns:reasontext"
760 : * minOccurs="1" maxOccurs="unbounded"/>
761 : * </xs:sequence>
762 : * </xs:complexType>
763 : *
764 : * <xs:complexType name="reasontext">
765 : * <xs:simpleContent>
766 : * <xs:extension base="xs:string">
767 : * <xs:attribute ref="xml:lang" use="required"/>
768 : * </xs:extension>
769 : * </xs:simpleContent>
770 : * </xs:complexType>
771 : *
772 : * <xs:simpleType name="faultcodeEnum">
773 : * <xs:restriction base="xs:QName">
774 : * <xs:enumeration value="tns:DataEncodingUnknown"/>
775 : * <xs:enumeration value="tns:MustUnderstand"/>
776 : * <xs:enumeration value="tns:Receiver"/>
777 : * <xs:enumeration value="tns:Sender"/>
778 : * <xs:enumeration value="tns:VersionMismatch"/>
779 : * </xs:restriction>
780 : * </xs:simpleType>
781 : *
782 : * <xs:complexType name="subcode">
783 : * <xs:sequence>
784 : * <xs:element name="Value" type="xs:QName"/>
785 : * <xs:element name="Subcode" type="tns:subcode" minOccurs="0"/>
786 : * </xs:sequence>
787 : * </xs:complexType>
788 : *
789 : * <xs:complexType name="detail">
790 : * <xs:sequence>
791 : * <xs:any namespace="##any" processContents="lax"
792 : * minOccurs="0" maxOccurs="unbounded"/>
793 : * </xs:sequence>
794 : * <xs:anyAttribute namespace="##other" processContents="lax"/>
795 : * </xs:complexType>
796 : *
797 : * Returns: pointer to the added entry or NULL if an error occurs.
798 : */
799 : xmlNodePtr
800 0 : xmlSecSoap12AddFaultEntry(xmlNodePtr envNode, xmlSecSoap12FaultCode faultCode,
801 : const xmlChar* faultReasonText, const xmlChar* faultReasonLang,
802 : const xmlChar* faultNodeURI, const xmlChar* faultRole) {
803 : xmlNodePtr bodyNode;
804 : xmlNodePtr faultNode;
805 : xmlNodePtr cur;
806 : int ret;
807 :
808 0 : xmlSecAssert2(envNode != NULL, NULL);
809 0 : xmlSecAssert2(faultCode != xmlSecSoap12FaultCodeUnknown, NULL);
810 0 : xmlSecAssert2(faultReasonText != NULL, NULL);
811 0 : xmlSecAssert2(faultReasonLang != NULL, NULL);
812 :
813 : /* get Body node */
814 0 : bodyNode = xmlSecSoap12GetBody(envNode);
815 0 : if(bodyNode == NULL) {
816 0 : xmlSecError(XMLSEC_ERRORS_HERE,
817 : NULL,
818 : "xmlSecSoap12GetBody",
819 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
820 : XMLSEC_ERRORS_NO_MESSAGE);
821 0 : return(NULL);
822 : }
823 :
824 : /* check that we don't have Fault node already */
825 0 : faultNode = xmlSecFindChild(bodyNode, xmlSecNodeFault, xmlSecSoap12Ns);
826 0 : if(faultNode != NULL) {
827 0 : xmlSecError(XMLSEC_ERRORS_HERE,
828 : NULL,
829 : xmlSecErrorsSafeString(xmlSecNodeBody),
830 : XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
831 : XMLSEC_ERRORS_NO_MESSAGE);
832 0 : return(NULL);
833 : }
834 :
835 : /* add Fault node */
836 0 : faultNode = xmlSecAddChild(bodyNode, xmlSecNodeFault, xmlSecSoap12Ns);
837 0 : if(faultNode == NULL) {
838 0 : xmlSecError(XMLSEC_ERRORS_HERE,
839 : NULL,
840 : "xmlSecAddChild",
841 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
842 : "node=%s",
843 : xmlSecErrorsSafeString(xmlSecNodeFault));
844 0 : return(NULL);
845 : }
846 :
847 : /* add Code node */
848 0 : cur = xmlSecAddChild(faultNode, xmlSecNodeCode, xmlSecSoap12Ns);
849 0 : if(cur == NULL) {
850 0 : xmlSecError(XMLSEC_ERRORS_HERE,
851 : NULL,
852 : "xmlSecAddChild",
853 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
854 : "node=%s",
855 : xmlSecErrorsSafeString(xmlSecNodeCode));
856 0 : xmlUnlinkNode(faultNode);
857 0 : xmlFreeNode(faultNode);
858 0 : return(NULL);
859 : }
860 :
861 : /* write the fault code in Value child */
862 0 : ret = xmlSecQName2IntegerNodeWrite(gXmlSecSoap12FaultCodeInfo, cur,
863 : xmlSecNodeValue, xmlSecSoap12Ns,
864 : faultCode);
865 0 : if(ret < 0) {
866 0 : xmlSecError(XMLSEC_ERRORS_HERE,
867 : NULL,
868 : "xmlSecQName2IntegerNodeWrite",
869 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
870 : "faultCode=%d",
871 : faultCode);
872 0 : xmlUnlinkNode(faultNode);
873 0 : xmlFreeNode(faultNode);
874 0 : return(NULL);
875 : }
876 :
877 : /* add Reason node */
878 0 : cur = xmlSecAddChild(faultNode, xmlSecNodeReason, xmlSecSoap12Ns);
879 0 : if(cur == NULL) {
880 0 : xmlSecError(XMLSEC_ERRORS_HERE,
881 : NULL,
882 : "xmlSecAddChild",
883 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
884 : "node=%s",
885 : xmlSecErrorsSafeString(xmlSecNodeReason));
886 0 : xmlUnlinkNode(faultNode);
887 0 : xmlFreeNode(faultNode);
888 0 : return(NULL);
889 : }
890 :
891 : /* Add Reason/Text node */
892 0 : if(xmlSecSoap12AddFaultReasonText(faultNode, faultReasonText, faultReasonLang) == NULL) {
893 0 : xmlSecError(XMLSEC_ERRORS_HERE,
894 : NULL,
895 : "xmlSecSoap12AddFaultReasonText",
896 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
897 : "text=%s",
898 : xmlSecErrorsSafeString(faultReasonText));
899 0 : xmlUnlinkNode(faultNode);
900 0 : xmlFreeNode(faultNode);
901 0 : return(NULL);
902 : }
903 :
904 0 : if(faultNodeURI != NULL) {
905 : /* add Node node */
906 0 : cur = xmlSecAddChild(faultNode, xmlSecNodeNode, xmlSecSoap12Ns);
907 0 : if(cur == NULL) {
908 0 : xmlSecError(XMLSEC_ERRORS_HERE,
909 : NULL,
910 : "xmlSecAddChild",
911 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
912 : "node=%s",
913 : xmlSecErrorsSafeString(xmlSecNodeNode));
914 0 : xmlUnlinkNode(faultNode);
915 0 : xmlFreeNode(faultNode);
916 0 : return(NULL);
917 : }
918 0 : xmlNodeSetContent(cur, faultNodeURI);
919 : }
920 :
921 0 : if(faultRole != NULL) {
922 : /* add Role node */
923 0 : cur = xmlSecAddChild(faultNode, xmlSecNodeRole, xmlSecSoap12Ns);
924 0 : if(cur == NULL) {
925 0 : xmlSecError(XMLSEC_ERRORS_HERE,
926 : NULL,
927 : "xmlSecAddChild",
928 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
929 : "node=%s",
930 : xmlSecErrorsSafeString(xmlSecNodeRole));
931 0 : xmlUnlinkNode(faultNode);
932 0 : xmlFreeNode(faultNode);
933 0 : return(NULL);
934 : }
935 0 : xmlNodeSetContent(cur, faultRole);
936 : }
937 :
938 0 : return(faultNode);
939 : }
940 :
941 : /**
942 : * xmlSecSoap12AddFaultSubcode:
943 : * @faultNode: the pointer to <Fault> node.
944 : * @subCodeHref: the subcode href.
945 : * @subCodeName: the subcode name.
946 : *
947 : * Adds a new <Subcode> node to the <Code> node or the last <Subcode> node.
948 : *
949 : * Returns: a pointer to the newly created <Subcode> node or NULL if an error
950 : * occurs.
951 : */
952 : xmlNodePtr
953 0 : xmlSecSoap12AddFaultSubcode(xmlNodePtr faultNode, const xmlChar* subCodeHref, const xmlChar* subCodeName) {
954 : xmlNodePtr cur, subcodeNode, valueNode;
955 : xmlChar* qname;
956 :
957 0 : xmlSecAssert2(faultNode != NULL, NULL);
958 0 : xmlSecAssert2(subCodeHref != NULL, NULL);
959 0 : xmlSecAssert2(subCodeName != NULL, NULL);
960 :
961 : /* Code node is the first childern in Fault node */
962 0 : cur = xmlSecGetNextElementNode(faultNode->children);
963 0 : if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeCode, xmlSecSoap12Ns)) {
964 0 : xmlSecError(XMLSEC_ERRORS_HERE,
965 : NULL,
966 : NULL,
967 : XMLSEC_ERRORS_R_INVALID_NODE,
968 : "node=%s",
969 : xmlSecErrorsSafeString(xmlSecNodeCode));
970 0 : return(NULL);
971 : }
972 :
973 : /* find the Code or Subcode node that does not have Subcode child */
974 : while(1) {
975 : xmlNodePtr tmp;
976 :
977 0 : tmp = xmlSecFindChild(cur, xmlSecNodeSubcode, xmlSecSoap12Ns);
978 0 : if(tmp != NULL) {
979 0 : cur = tmp;
980 : } else {
981 0 : break;
982 : }
983 0 : }
984 0 : xmlSecAssert2(cur != NULL, NULL);
985 :
986 : /* add Subcode node */
987 0 : subcodeNode = xmlSecAddChild(cur, xmlSecNodeSubcode, xmlSecSoap12Ns);
988 0 : if(subcodeNode == NULL) {
989 0 : xmlSecError(XMLSEC_ERRORS_HERE,
990 : NULL,
991 : "xmlSecAddChild",
992 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
993 : "node=%s",
994 : xmlSecErrorsSafeString(xmlSecNodeSubcode));
995 0 : return(NULL);
996 : }
997 :
998 : /* add Value node */
999 0 : valueNode = xmlSecAddChild(subcodeNode, xmlSecNodeValue, xmlSecSoap12Ns);
1000 0 : if(valueNode == NULL) {
1001 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1002 : NULL,
1003 : "xmlSecAddChild",
1004 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1005 : "node=%s",
1006 : xmlSecErrorsSafeString(xmlSecNodeValue));
1007 0 : xmlUnlinkNode(subcodeNode);
1008 0 : xmlFreeNode(subcodeNode);
1009 0 : return(NULL);
1010 : }
1011 :
1012 : /* create qname for fault code */
1013 0 : qname = xmlSecGetQName(cur, subCodeHref, subCodeName);
1014 0 : if(qname == NULL) {
1015 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1016 : NULL,
1017 : "xmlSecGetQName",
1018 : XMLSEC_ERRORS_R_XML_FAILED,
1019 : "node=%s",
1020 0 : xmlSecErrorsSafeString(cur->name));
1021 0 : xmlUnlinkNode(subcodeNode);
1022 0 : xmlFreeNode(subcodeNode);
1023 0 : return(NULL);
1024 : }
1025 :
1026 : /* set result qname in Value node */
1027 0 : xmlNodeSetContent(cur, qname);
1028 0 : if(qname != subCodeName) {
1029 0 : xmlFree(qname);
1030 : }
1031 :
1032 0 : return(subcodeNode);
1033 : }
1034 :
1035 : /**
1036 : * xmlSecSoap12AddFaultReasonText:
1037 : * @faultNode: the pointer to <Fault> node.
1038 : * @faultReasonText: the new reason text.
1039 : * @faultReasonLang: the new reason xml:lang attribute.
1040 : *
1041 : * Adds a new Text node to the Fault/Reason node.
1042 : *
1043 : * Returns: a pointer to the newly created <Text> node or NULL if an error
1044 : * occurs.
1045 : */
1046 : xmlNodePtr
1047 0 : xmlSecSoap12AddFaultReasonText(xmlNodePtr faultNode, const xmlChar* faultReasonText,
1048 : const xmlChar* faultReasonLang) {
1049 : xmlNodePtr reasonNode;
1050 : xmlNodePtr textNode;
1051 :
1052 0 : xmlSecAssert2(faultNode != NULL, NULL);
1053 0 : xmlSecAssert2(faultReasonText != NULL, NULL);
1054 0 : xmlSecAssert2(faultReasonLang != NULL, NULL);
1055 :
1056 : /* find Reason node */
1057 0 : reasonNode = xmlSecFindChild(faultNode, xmlSecNodeReason, xmlSecSoap12Ns);
1058 0 : if(reasonNode == NULL) {
1059 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1060 : NULL,
1061 : "xmlSecFindChild",
1062 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1063 : "node=%s",
1064 : xmlSecErrorsSafeString(xmlSecNodeReason));
1065 0 : return(NULL);
1066 : }
1067 :
1068 : /* add Text node */
1069 0 : textNode = xmlSecAddChild(reasonNode, xmlSecNodeText, xmlSecSoap12Ns);
1070 0 : if(textNode == NULL) {
1071 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1072 : NULL,
1073 : "xmlSecAddChild",
1074 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1075 : "node=%s",
1076 : xmlSecErrorsSafeString(xmlSecNodeText));
1077 0 : return(NULL);
1078 : }
1079 0 : xmlNodeSetContent(textNode, faultReasonText);
1080 0 : xmlNodeSetLang(textNode, faultReasonLang);
1081 :
1082 0 : return(textNode);
1083 : }
1084 :
1085 : /**
1086 : * xmlSecSoap12AddFaultDetailEntry:
1087 : * @faultNode: the pointer to <Fault> node.
1088 : * @detailEntryNode: the pointer to detail entry node.
1089 : *
1090 : * Adds a new child to the Detail child element of @faultNode.
1091 : *
1092 : * Returns: pointer to the added child (@detailEntryNode) or NULL if an error
1093 : * occurs.
1094 : */
1095 : xmlNodePtr
1096 0 : xmlSecSoap12AddFaultDetailEntry(xmlNodePtr faultNode, xmlNodePtr detailEntryNode) {
1097 : xmlNodePtr detailNode;
1098 :
1099 0 : xmlSecAssert2(faultNode != NULL, NULL);
1100 0 : xmlSecAssert2(detailEntryNode != NULL, NULL);
1101 :
1102 : /* find Detail node and add it if needed */
1103 0 : detailNode = xmlSecFindChild(faultNode, xmlSecNodeDetail, xmlSecSoap12Ns);
1104 0 : if(detailNode == NULL) {
1105 0 : detailNode = xmlSecAddChild(faultNode, xmlSecNodeDetail, xmlSecSoap12Ns);
1106 0 : if(detailNode == NULL) {
1107 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1108 : NULL,
1109 : "xmlSecAddChild",
1110 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1111 : "node=%s",
1112 : xmlSecErrorsSafeString(xmlSecNodeDetail));
1113 0 : return(NULL);
1114 : }
1115 : }
1116 :
1117 0 : return(xmlSecAddChildNode(detailNode, detailEntryNode));
1118 : }
1119 :
1120 : /**
1121 : * xmlSecSoap12CheckEnvelope:
1122 : * @envNode: the pointer to <soap:Envelope> node.
1123 : *
1124 : * Validates <soap:Envelope> node structure.
1125 : *
1126 : * Returns: 1 if @envNode has a valid <soap:Envelope> element, 0 if it is
1127 : * not valid or a negative value if an error occurs.
1128 : */
1129 : int
1130 0 : xmlSecSoap12CheckEnvelope(xmlNodePtr envNode) {
1131 : xmlNodePtr cur;
1132 :
1133 0 : xmlSecAssert2(envNode != NULL, -1);
1134 :
1135 : /* verify envNode itself */
1136 0 : if(!xmlSecCheckNodeName(envNode, xmlSecNodeEnvelope, xmlSecSoap12Ns)) {
1137 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1138 : NULL,
1139 : xmlSecErrorsSafeString(xmlSecNodeEnvelope),
1140 : XMLSEC_ERRORS_R_NODE_NOT_FOUND,
1141 : XMLSEC_ERRORS_NO_MESSAGE);
1142 0 : return(0);
1143 : }
1144 :
1145 : /* optional Header node first */
1146 0 : cur = xmlSecGetNextElementNode(envNode->children);
1147 0 : if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHeader, xmlSecSoap12Ns)) {
1148 0 : cur = xmlSecGetNextElementNode(cur->next);
1149 : }
1150 :
1151 : /* required Body node is next */
1152 0 : if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeBody, xmlSecSoap12Ns)) {
1153 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1154 : NULL,
1155 : xmlSecErrorsSafeString(xmlSecNodeBody),
1156 : XMLSEC_ERRORS_R_NODE_NOT_FOUND,
1157 : XMLSEC_ERRORS_NO_MESSAGE);
1158 0 : return(0);
1159 : }
1160 :
1161 0 : return(1);
1162 : }
1163 :
1164 : /**
1165 : * xmlSecSoap12GetHeader:
1166 : * @envNode: the pointer to <soap:Envelope> node.
1167 : *
1168 : * Gets pointer to the <soap:Header> node.
1169 : *
1170 : * Returns: pointer to <soap:Header> node or NULL if an error occurs.
1171 : */
1172 : xmlNodePtr
1173 0 : xmlSecSoap12GetHeader(xmlNodePtr envNode) {
1174 : xmlNodePtr cur;
1175 :
1176 0 : xmlSecAssert2(envNode != NULL, NULL);
1177 :
1178 : /* optional Header node is first */
1179 0 : cur = xmlSecGetNextElementNode(envNode->children);
1180 0 : if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHeader, xmlSecSoap12Ns)) {
1181 0 : return(cur);
1182 : }
1183 :
1184 0 : return(NULL);
1185 : }
1186 :
1187 : /**
1188 : * xmlSecSoap12GetBody:
1189 : * @envNode: the pointer to <soap:Envelope> node.
1190 : *
1191 : * Gets pointer to the <soap:Body> node.
1192 : *
1193 : * Returns: pointer to <soap:Body> node or NULL if an error occurs.
1194 : */
1195 : xmlNodePtr
1196 0 : xmlSecSoap12GetBody(xmlNodePtr envNode) {
1197 : xmlNodePtr cur;
1198 :
1199 0 : xmlSecAssert2(envNode != NULL, NULL);
1200 :
1201 : /* optional Header node first */
1202 0 : cur = xmlSecGetNextElementNode(envNode->children);
1203 0 : if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHeader, xmlSecSoap12Ns)) {
1204 0 : cur = xmlSecGetNextElementNode(cur->next);
1205 : }
1206 :
1207 : /* Body node is next */
1208 0 : if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeBody, xmlSecSoap12Ns)) {
1209 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1210 : NULL,
1211 : xmlSecErrorsSafeString(xmlSecNodeBody),
1212 : XMLSEC_ERRORS_R_NODE_NOT_FOUND,
1213 : XMLSEC_ERRORS_NO_MESSAGE);
1214 0 : return(NULL);
1215 : }
1216 :
1217 0 : return(cur);
1218 : }
1219 :
1220 : /**
1221 : * xmlSecSoap12GetBodyEntriesNumber:
1222 : * @envNode: the pointer to <soap:Envelope> node.
1223 : *
1224 : * Gets the number of body entries.
1225 : *
1226 : * Returns: the number of body entries.
1227 : */
1228 : xmlSecSize
1229 0 : xmlSecSoap12GetBodyEntriesNumber(xmlNodePtr envNode) {
1230 0 : xmlSecSize number = 0;
1231 : xmlNodePtr bodyNode;
1232 : xmlNodePtr cur;
1233 :
1234 0 : xmlSecAssert2(envNode != NULL, 0);
1235 :
1236 : /* get Body node */
1237 0 : bodyNode = xmlSecSoap12GetBody(envNode);
1238 0 : if(bodyNode == NULL) {
1239 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1240 : NULL,
1241 : "xmlSecSoap12GetBody",
1242 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1243 : XMLSEC_ERRORS_NO_MESSAGE);
1244 0 : return(0);
1245 : }
1246 :
1247 0 : cur = xmlSecGetNextElementNode(bodyNode->children);
1248 0 : while(cur != NULL) {
1249 0 : number++;
1250 0 : cur = xmlSecGetNextElementNode(cur->next);
1251 : }
1252 :
1253 0 : return(number);
1254 : }
1255 :
1256 : /**
1257 : * xmlSecSoap12GetBodyEntry:
1258 : * @envNode: the pointer to <soap:Envelope> node.
1259 : * @pos: the body entry number.
1260 : *
1261 : * Gets the body entry number @pos.
1262 : *
1263 : * Returns: pointer to body entry node or NULL if an error occurs.
1264 : */
1265 : xmlNodePtr
1266 0 : xmlSecSoap12GetBodyEntry(xmlNodePtr envNode, xmlSecSize pos) {
1267 : xmlNodePtr bodyNode;
1268 : xmlNodePtr cur;
1269 :
1270 0 : xmlSecAssert2(envNode != NULL, NULL);
1271 :
1272 : /* get Body node */
1273 0 : bodyNode = xmlSecSoap12GetBody(envNode);
1274 0 : if(bodyNode == NULL) {
1275 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1276 : NULL,
1277 : "xmlSecSoap12GetBody",
1278 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1279 : XMLSEC_ERRORS_NO_MESSAGE);
1280 0 : return(NULL);
1281 : }
1282 :
1283 0 : cur = xmlSecGetNextElementNode(bodyNode->children);
1284 0 : while((cur != NULL) && (pos > 0)) {
1285 0 : pos--;
1286 0 : cur = xmlSecGetNextElementNode(cur->next);
1287 : }
1288 :
1289 0 : return(cur);
1290 : }
1291 :
1292 : /**
1293 : * xmlSecSoap12GetFaultEntry:
1294 : * @envNode: the pointer to <soap:Envelope> node.
1295 : *
1296 : * Gets the Fault entry (if any).
1297 : *
1298 : * Returns: pointer to Fault entry or NULL if it does not exist.
1299 : */
1300 : xmlNodePtr
1301 0 : xmlSecSoap12GetFaultEntry(xmlNodePtr envNode) {
1302 : xmlNodePtr bodyNode;
1303 :
1304 0 : xmlSecAssert2(envNode != NULL, NULL);
1305 :
1306 : /* get Body node */
1307 0 : bodyNode = xmlSecSoap12GetBody(envNode);
1308 0 : if(bodyNode == NULL) {
1309 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1310 : NULL,
1311 : "xmlSecSoap12GetBody",
1312 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1313 : XMLSEC_ERRORS_NO_MESSAGE);
1314 0 : return(NULL);
1315 : }
1316 :
1317 0 : return(xmlSecFindChild(bodyNode, xmlSecNodeFault, xmlSecSoap12Ns));
1318 : }
1319 :
1320 : #endif /* XMLSEC_NO_SOAP */
1321 :
1322 :
|