/**
 * xmlSecSoap12AddFaultDetailEntry:
 * @faultNode:          the pointer to <Fault> node.
 * @detailEntryNode:    the pointer to detail entry node.
 * 
 * Adds a new child to the Detail child element of @faultNode.
 *
 * Returns pointer to the added child (@detailEntryNode) or NULL if an error 
 * occurs.
 */
EXPORT_C
xmlNodePtr 
xmlSecSoap12AddFaultDetailEntry(xmlNodePtr faultNode, xmlNodePtr detailEntryNode) {
    xmlNodePtr detailNode;

    xmlSecAssert2(faultNode != NULL, NULL);
    xmlSecAssert2(detailEntryNode != NULL, NULL);

    /* find Detail node and add it if needed */
    detailNode = xmlSecFindChild(faultNode,  xmlSecNodeDetail, xmlSecSoap12Ns);
    if(detailNode == NULL) {
        detailNode = xmlSecAddChild(faultNode, xmlSecNodeDetail, xmlSecSoap12Ns);
        if(detailNode == NULL) {
    	    xmlSecError(XMLSEC_ERRORS_HERE,
		        NULL,
		        "xmlSecAddChild",
		        XMLSEC_ERRORS_R_XMLSEC_FAILED,
		        "node=%s",
		        xmlSecErrorsSafeString(xmlSecNodeDetail));
	    return(NULL);	        	
        }
    }
    
    return(xmlSecAddChildNode(detailNode, detailEntryNode));
}
/**
 * xmlSecSoap12CreateEnvelope:
 * @doc:        the parent doc (might be NULL).
 * 
 * Creates a new SOAP 1.2 Envelope node. Caller is responsible for 
 * adding the returned node to the XML document.
 *
 * XML Schema (http://www.w3.org/2003/05/soap-envelope):
 * 
 *     <xs:element name="Envelope" type="tns:Envelope"/>
 *     <xs:complexType name="Envelope">
 *         <xs:sequence>
 *             <xs:element ref="tns:Header" minOccurs="0"/>
 *             <xs:element ref="tns:Body" minOccurs="1"/>
 *         </xs:sequence>
 *         <xs:anyAttribute namespace="##other" processContents="lax"/>
 *     </xs:complexType>
 *
 * Returns pointer to newly created <soap:Envelope> node or NULL
 * if an error occurs.
 */
EXPORT_C
xmlNodePtr 
xmlSecSoap12CreateEnvelope(xmlDocPtr doc) {
    xmlNodePtr envNode;
    xmlNodePtr bodyNode;
    xmlNsPtr ns;
    
    /* create Envelope node */
    envNode = xmlNewDocNode(doc, NULL, xmlSecNodeEnvelope, NULL);
    if(envNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewDocNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeEnvelope));
	return(NULL);	            
    }
    
    ns = xmlNewNs(envNode, xmlSecSoap12Ns, NULL) ;
    if(ns == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewNs",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "ns=%s",
		    xmlSecErrorsSafeString(xmlSecSoap12Ns));
	xmlFreeNode(envNode);
	return(NULL);	        	
    }
    xmlSetNs(envNode, ns);
    
    /* add required Body node */    
    bodyNode = xmlSecAddChild(envNode, xmlSecNodeBody, xmlSecSoap12Ns);
    if(bodyNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeBody));
	xmlFreeNode(envNode);
	return(NULL);	        	
    }
    
    return(envNode);
}
/**
 * xmlSecSoap12AddFaultReasonText:
 * @faultNode:          the pointer to <Fault> node.
 * @faultReasonText:    the new reason text.
 * @faultReasonLang:    the new reason xml:lang attribute.
 *
 * Adds a new Text node to the Fault/Reason node.
 *
 * Returns a pointer to the newly created <Text> node or NULL if an error
 * occurs.
 */
EXPORT_C
xmlNodePtr 
xmlSecSoap12AddFaultReasonText(xmlNodePtr faultNode, const xmlChar* faultReasonText, 
                               const xmlChar* faultReasonLang) {
    xmlNodePtr reasonNode;
    xmlNodePtr textNode;

    xmlSecAssert2(faultNode != NULL, NULL);
    xmlSecAssert2(faultReasonText != NULL, NULL);
    xmlSecAssert2(faultReasonLang != NULL, NULL);

    /* find Reason node */
    reasonNode = xmlSecFindChild(faultNode,  xmlSecNodeReason, xmlSecSoap12Ns);
    if(reasonNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecFindChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeReason));
	return(NULL);	        	
    }

    /* add Text node */
    textNode = xmlSecAddChild(reasonNode, xmlSecNodeText, xmlSecSoap12Ns);
    if(textNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeText));
	return(NULL);	        	
    }
    xmlNodeSetContent(textNode, faultReasonText);
    xmlNodeSetLang(textNode, faultReasonLang);

    return(textNode);
}
Exemple #4
0
/** 
 * xmlSecSimpleKeysStoreSave:
 * @store:		the pointer to simple keys store.
 * @filename:		the filename.
 * @type:		the saved keys type (public, private, ...).
 * 
 * Writes keys from @store to an XML file.
 *
 * Returns 0 on success or a negative value if an error occurs.
 */
int
xmlSecSimpleKeysStoreSave(xmlSecKeyStorePtr store, const char *filename, xmlSecKeyDataType type) {
    xmlSecKeyInfoCtx keyInfoCtx;
    xmlSecPtrListPtr list;
    xmlSecKeyPtr key;
    xmlSecSize i, keysSize;    
    xmlDocPtr doc;
    xmlNodePtr cur;
    xmlSecKeyDataPtr data;
    xmlSecPtrListPtr idsList;
    xmlSecKeyDataId dataId;
    xmlSecSize idsSize, j;
    int ret;

    xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), -1);
    xmlSecAssert2(filename != NULL, -1);    

    list = xmlSecSimpleKeysStoreGetList(store);
    xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyPtrListId), -1);

    /* create doc */
    doc = xmlSecCreateTree(BAD_CAST "Keys", xmlSecNs);
    if(doc == NULL) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
		    "xmlSecCreateTree",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	return(-1);
    }
    
    idsList = xmlSecKeyDataIdsGet();	
    xmlSecAssert2(idsList != NULL, -1);
	
    keysSize = xmlSecPtrListGetSize(list);
    idsSize = xmlSecPtrListGetSize(idsList);
    for(i = 0; i < keysSize; ++i) {
	key = (xmlSecKeyPtr)xmlSecPtrListGetItem(list, i);
	xmlSecAssert2(key != NULL, -1);
	    
    	cur = xmlSecAddChild(xmlDocGetRootElement(doc), xmlSecNodeKeyInfo, xmlSecDSigNs);
	if(cur == NULL) {
	    xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE,
			xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
			"xmlSecAddChild",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			"node=%s",
			xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
	    xmlFreeDoc(doc); 
	    return(-1);
	}

	/* special data key name */
	if(xmlSecKeyGetName(key) != NULL) {
    	    if(xmlSecAddChild(cur, xmlSecNodeKeyName, xmlSecDSigNs) == NULL) {
		xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE,
			    xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
			    "xmlSecAddChild",
			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
			    "node=%s",
			    xmlSecErrorsSafeString(xmlSecNodeKeyName));
		xmlFreeDoc(doc); 
		return(-1);
	    }
	}
    
	/* create nodes for other keys data */
	for(j = 0; j < idsSize; ++j) {
	    dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(idsList, j);
	    xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, -1);

	    if(dataId->dataNodeName == NULL) {
		continue;
	    }
	    
	    data = xmlSecKeyGetData(key, dataId);
	    if(data == NULL) {
		continue;
	    }

	    if(xmlSecAddChild(cur, dataId->dataNodeName, dataId->dataNodeNs) == NULL) {
		xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE,
			    xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
			    "xmlSecAddChild",
			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
			    "node=%s", 
			    xmlSecErrorsSafeString(dataId->dataNodeName));
		xmlFreeDoc(doc); 
	        return(-1);
	    }
	}

    	ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx, NULL);
	if(ret < 0) {
	    xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    	xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
			"xmlSecKeyInfoCtxInitialize",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			XMLSEC_ERRORS_NO_MESSAGE);
	    xmlFreeDoc(doc);
	    return(-1);
	}

	keyInfoCtx.mode 		= xmlSecKeyInfoModeWrite;
    	keyInfoCtx.keyReq.keyId		= xmlSecKeyDataIdUnknown;
	keyInfoCtx.keyReq.keyType	= type;
	keyInfoCtx.keyReq.keyUsage 	= xmlSecKeyDataUsageAny;

	/* finally write key in the node */
	ret = xmlSecKeyInfoNodeWrite(cur, key, &keyInfoCtx);
	if(ret < 0) {
	    xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
			xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
			"xmlSecKeyInfoNodeWrite",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			XMLSEC_ERRORS_NO_MESSAGE);
	    xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
	    xmlFreeDoc(doc); 
	    return(-1);
	}		
	xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
    }
    
    /* now write result */
    ret = xmlSaveFormatFile(filename, doc, 1);
    if(ret < 0) {
	xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE,
		    xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
		    "xmlSaveFormatFile",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "filename=%s", 
		    xmlSecErrorsSafeString(filename));
	xmlFreeDoc(doc); 
	return(-1);
    }	   
    
    xmlFreeDoc(doc);
    return(0);
}
Exemple #5
0
/**
 * xmlSecSoap12AddFaultSubcode:
 * @faultNode:          the pointer to <Fault> node.
 * @subCodeHref:        the subcode href.
 * @subCodeName:        the subcode name.
 *
 * Adds a new <Subcode> node to the <Code> node or the last <Subcode> node.
 *
 * Returns: a pointer to the newly created <Subcode> node or NULL if an error
 * occurs.
 */
xmlNodePtr
xmlSecSoap12AddFaultSubcode(xmlNodePtr faultNode, const xmlChar* subCodeHref, const xmlChar* subCodeName) {
    xmlNodePtr cur, subcodeNode, valueNode;
    xmlChar* qname;

    xmlSecAssert2(faultNode != NULL, NULL);
    xmlSecAssert2(subCodeHref != NULL, NULL);
    xmlSecAssert2(subCodeName != NULL, NULL);

    /* Code node is the first childern in Fault node */
    cur = xmlSecGetNextElementNode(faultNode->children);
    if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeCode, xmlSecSoap12Ns)) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    NULL,
                    XMLSEC_ERRORS_R_INVALID_NODE,
                    "node=%s",
                    xmlSecErrorsSafeString(xmlSecNodeCode));
        return(NULL);
    }

    /* find the Code or Subcode node that does not have Subcode child */
    while(1) {
        xmlNodePtr tmp;

        tmp = xmlSecFindChild(cur, xmlSecNodeSubcode, xmlSecSoap12Ns);
        if(tmp != NULL) {
            cur = tmp;
        } else {
            break;
        }
    }
    xmlSecAssert2(cur != NULL, NULL);

    /* add Subcode node */
    subcodeNode = xmlSecAddChild(cur, xmlSecNodeSubcode, xmlSecSoap12Ns);
    if(subcodeNode == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecAddChild",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "node=%s",
                    xmlSecErrorsSafeString(xmlSecNodeSubcode));
        return(NULL);
    }

    /* add Value node */
    valueNode = xmlSecAddChild(subcodeNode, xmlSecNodeValue, xmlSecSoap12Ns);
    if(valueNode == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecAddChild",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "node=%s",
                    xmlSecErrorsSafeString(xmlSecNodeValue));
        xmlUnlinkNode(subcodeNode);
        xmlFreeNode(subcodeNode);
        return(NULL);
    }

    /* create qname for fault code */
    qname = xmlSecGetQName(cur, subCodeHref, subCodeName);
    if(qname == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecGetQName",
                    XMLSEC_ERRORS_R_XML_FAILED,
                    "node=%s",
                    xmlSecErrorsSafeString(cur->name));
        xmlUnlinkNode(subcodeNode);
        xmlFreeNode(subcodeNode);
        return(NULL);
    }

    /* set result qname in Value node */
    xmlNodeSetContent(cur, qname);
    if(qname != subCodeName) {
        xmlFree(qname);
    }

    return(subcodeNode);
}
Exemple #6
0
/**
 * xmlSecSoap12AddFaultEntry:
 * @envNode:            the pointer to <soap:Envelope> node.
 * @faultCode:          the fault code.
 * @faultReasonText:    the human readable explanation of the fault.
 * @faultReasonLang:    the language (xml:lang) for @faultReason string.
 * @faultNodeURI:       the more preciese information about fault source
 *                      (might be NULL).
 * @faultRole:          the role the node was operating in at the point
 *                      the fault occurred (might be NULL).
 *
 * Adds <soap:Fault> entry to the @envNode. Note that only one <soap:Fault>
 * entry is allowed.
 *
 * XML Schema (http://www.w3.org/2003/05/soap-envelope):
 *
 *     <xs:element name="Fault" type="tns:Fault"/>
 *     <xs:complexType name="Fault" final="extension">
 *         <xs:sequence>
 *             <xs:element name="Code" type="tns:faultcode"/>
 *             <xs:element name="Reason" type="tns:faultreason"/>
 *             <xs:element name="Node" type="xs:anyURI" minOccurs="0"/>
 *             <xs:element name="Role" type="xs:anyURI" minOccurs="0"/>
 *             <xs:element name="Detail" type="tns:detail" minOccurs="0"/>
 *         </xs:sequence>
 *     </xs:complexType>
 *
 *     <xs:complexType name="faultcode">
 *         <xs:sequence>
 *             <xs:element name="Value" type="tns:faultcodeEnum"/>
 *             <xs:element name="Subcode" type="tns:subcode" minOccurs="0"/>
 *         </xs:sequence>
 *     </xs:complexType>
 *
 *     <xs:complexType name="faultreason">
 *         <xs:sequence>
 *             <xs:element name="Text" type="tns:reasontext"
 *                         minOccurs="1" maxOccurs="unbounded"/>
 *         </xs:sequence>
 *     </xs:complexType>
 *
 *     <xs:complexType name="reasontext">
 *         <xs:simpleContent>
 *             <xs:extension base="xs:string">
 *                 <xs:attribute ref="xml:lang" use="required"/>
 *             </xs:extension>
 *         </xs:simpleContent>
 *     </xs:complexType>
 *
 *     <xs:simpleType name="faultcodeEnum">
 *         <xs:restriction base="xs:QName">
 *             <xs:enumeration value="tns:DataEncodingUnknown"/>
 *             <xs:enumeration value="tns:MustUnderstand"/>
 *             <xs:enumeration value="tns:Receiver"/>
 *             <xs:enumeration value="tns:Sender"/>
 *             <xs:enumeration value="tns:VersionMismatch"/>
 *         </xs:restriction>
 *     </xs:simpleType>
 *
 *     <xs:complexType name="subcode">
 *         <xs:sequence>
 *             <xs:element name="Value" type="xs:QName"/>
 *             <xs:element name="Subcode" type="tns:subcode" minOccurs="0"/>
 *         </xs:sequence>
 *     </xs:complexType>
 *
 *     <xs:complexType name="detail">
 *         <xs:sequence>
 *             <xs:any namespace="##any" processContents="lax"
 *                 minOccurs="0" maxOccurs="unbounded"/>
 *         </xs:sequence>
 *         <xs:anyAttribute namespace="##other" processContents="lax"/>
 *     </xs:complexType>
 *
 * Returns: pointer to the added entry or NULL if an error occurs.
 */
xmlNodePtr
xmlSecSoap12AddFaultEntry(xmlNodePtr envNode, xmlSecSoap12FaultCode faultCode,
                         const xmlChar* faultReasonText, const xmlChar* faultReasonLang,
                         const xmlChar* faultNodeURI, const xmlChar* faultRole) {
    xmlNodePtr bodyNode;
    xmlNodePtr faultNode;
    xmlNodePtr cur;
    int ret;

    xmlSecAssert2(envNode != NULL, NULL);
    xmlSecAssert2(faultCode != xmlSecSoap12FaultCodeUnknown, NULL);
    xmlSecAssert2(faultReasonText != NULL, NULL);
    xmlSecAssert2(faultReasonLang != NULL, NULL);

    /* get Body node */
    bodyNode = xmlSecSoap12GetBody(envNode);
    if(bodyNode == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecSoap12GetBody",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        return(NULL);
    }

    /* check that we don't have Fault node already */
    faultNode = xmlSecFindChild(bodyNode, xmlSecNodeFault, xmlSecSoap12Ns);
    if(faultNode != NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    xmlSecErrorsSafeString(xmlSecNodeBody),
                    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
                    XMLSEC_ERRORS_NO_MESSAGE);
        return(NULL);
    }

    /* add Fault node */
    faultNode = xmlSecAddChild(bodyNode, xmlSecNodeFault, xmlSecSoap12Ns);
    if(faultNode == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecAddChild",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "node=%s",
                    xmlSecErrorsSafeString(xmlSecNodeFault));
        return(NULL);
    }

    /* add Code node */
    cur = xmlSecAddChild(faultNode, xmlSecNodeCode, xmlSecSoap12Ns);
    if(cur == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecAddChild",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "node=%s",
                    xmlSecErrorsSafeString(xmlSecNodeCode));
        xmlUnlinkNode(faultNode);
        xmlFreeNode(faultNode);
        return(NULL);
    }

    /* write the fault code in Value child */
    ret = xmlSecQName2IntegerNodeWrite(gXmlSecSoap12FaultCodeInfo, cur,
                                       xmlSecNodeValue, xmlSecSoap12Ns,
                                       faultCode);
    if(ret < 0) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecQName2IntegerNodeWrite",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "faultCode=%d",
                    faultCode);
        xmlUnlinkNode(faultNode);
        xmlFreeNode(faultNode);
        return(NULL);
    }

    /* add Reason node */
    cur = xmlSecAddChild(faultNode, xmlSecNodeReason, xmlSecSoap12Ns);
    if(cur == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecAddChild",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "node=%s",
                    xmlSecErrorsSafeString(xmlSecNodeReason));
        xmlUnlinkNode(faultNode);
        xmlFreeNode(faultNode);
        return(NULL);
    }

    /* Add Reason/Text node */
    if(xmlSecSoap12AddFaultReasonText(faultNode, faultReasonText, faultReasonLang) == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecSoap12AddFaultReasonText",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "text=%s",
                    xmlSecErrorsSafeString(faultReasonText));
        xmlUnlinkNode(faultNode);
        xmlFreeNode(faultNode);
        return(NULL);
    }

    if(faultNodeURI != NULL) {
        /* add Node node */
        cur = xmlSecAddChild(faultNode, xmlSecNodeNode, xmlSecSoap12Ns);
        if(cur == NULL) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        NULL,
                        "xmlSecAddChild",
                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
                        "node=%s",
                        xmlSecErrorsSafeString(xmlSecNodeNode));
            xmlUnlinkNode(faultNode);
            xmlFreeNode(faultNode);
            return(NULL);
        }
        xmlNodeSetContent(cur, faultNodeURI);
    }

    if(faultRole != NULL) {
        /* add Role node */
        cur = xmlSecAddChild(faultNode, xmlSecNodeRole, xmlSecSoap12Ns);
        if(cur == NULL) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        NULL,
                        "xmlSecAddChild",
                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
                        "node=%s",
                        xmlSecErrorsSafeString(xmlSecNodeRole));
            xmlUnlinkNode(faultNode);
            xmlFreeNode(faultNode);
            return(NULL);
        }
        xmlNodeSetContent(cur, faultRole);
    }

    return(faultNode);
}
Exemple #7
0
/**
 * xmlSecSoap11AddFaultEntry:
 * @envNode:            the pointer to <soap:Envelope> node.
 * @faultCodeHref:      the fault code QName href (must be known in th context of
 *                      <soap:Body> node).
 * @faultCodeLocalPart: the fault code QName LocalPart.
 * @faultString:        the human readable explanation of the fault.
 * @faultActor:         the information about who caused the fault (might be NULL).
 *
 * Adds <soap:Fault> entry to the @envNode. Note that only one <soap:Fault>
 * entry is allowed.
 *
 * XML Schema (http://schemas.xmlsoap.org/soap/envelope/):
 *
 *     <xs:element name="Fault" type="tns:Fault"/>
 *     <xs:complexType name="Fault" final="extension">
 *         <xs:sequence>
 *             <xs:element name="faultcode" type="xs:QName"/>
 *             <xs:element name="faultstring" type="xs:string"/>
 *             <xs:element name="faultactor" type="xs:anyURI" minOccurs="0"/>
 *             <xs:element name="detail" type="tns:detail" minOccurs="0"/>
 *         </xs:sequence>
 *     </xs:complexType>
 *     <xs:complexType name="detail">
 *         <xs:sequence>
 *             <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded"
 *                 processContents="lax"/>
 *         </xs:sequence>
 *         <xs:anyAttribute namespace="##any" processContents="lax"/>
 *     </xs:complexType>
 *
 * Returns: pointer to the added entry or NULL if an error occurs.
 */
xmlNodePtr
xmlSecSoap11AddFaultEntry(xmlNodePtr envNode, const xmlChar* faultCodeHref,
                          const xmlChar* faultCodeLocalPart,
                          const xmlChar* faultString, const xmlChar* faultActor) {
    xmlNodePtr bodyNode;
    xmlNodePtr faultNode;
    xmlNodePtr cur;
    xmlChar* qname;

    xmlSecAssert2(envNode != NULL, NULL);
    xmlSecAssert2(faultCodeLocalPart != NULL, NULL);
    xmlSecAssert2(faultString != NULL, NULL);

    /* get Body node */
    bodyNode = xmlSecSoap11GetBody(envNode);
    if(bodyNode == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecSoap11GetBody",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        return(NULL);
    }

    /* check that we don't have Fault node already */
    faultNode = xmlSecFindChild(bodyNode, xmlSecNodeFault, xmlSecSoap11Ns);
    if(faultNode != NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    xmlSecErrorsSafeString(xmlSecNodeBody),
                    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
                    XMLSEC_ERRORS_NO_MESSAGE);
        return(NULL);
    }

    /* add Fault node */
    faultNode = xmlSecAddChild(bodyNode, xmlSecNodeFault, xmlSecSoap11Ns);
    if(faultNode == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecAddChild",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "node=%s",
                    xmlSecErrorsSafeString(xmlSecNodeFault));
        return(NULL);
    }

    /* add faultcode node */
    cur = xmlSecAddChild(faultNode, xmlSecNodeFaultCode, xmlSecSoap11Ns);
    if(cur == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecAddChild",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "node=%s",
                    xmlSecErrorsSafeString(xmlSecNodeFaultCode));
        xmlUnlinkNode(faultNode);
        xmlFreeNode(faultNode);
        return(NULL);
    }

    /* create qname for fault code */
    qname = xmlSecGetQName(cur, faultCodeHref, faultCodeLocalPart);
    if(qname == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecGetQName",
                    XMLSEC_ERRORS_R_XML_FAILED,
                    "node=%s",
                    xmlSecErrorsSafeString(cur->name));
        xmlUnlinkNode(faultNode);
        xmlFreeNode(faultNode);
        return(NULL);
    }

    /* set faultcode value */
    xmlNodeSetContent(cur, qname);
    xmlFree(qname);

    /* add faultstring node */
    cur = xmlSecAddChild(faultNode, xmlSecNodeFaultString, xmlSecSoap11Ns);
    if(cur == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecAddChild",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "node=%s",
                    xmlSecErrorsSafeString(xmlSecNodeFaultString));
        xmlUnlinkNode(faultNode);
        xmlFreeNode(faultNode);
        return(NULL);
    }

    /* set faultstring node */
    xmlNodeSetContent(cur, faultString);

    if(faultActor != NULL) {
        /* add faultactor node */
        cur = xmlSecAddChild(faultNode, xmlSecNodeFaultActor, xmlSecSoap11Ns);
        if(cur == NULL) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        NULL,
                        "xmlSecAddChild",
                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
                        "node=%s",
                        xmlSecErrorsSafeString(xmlSecNodeFaultActor));
            xmlUnlinkNode(faultNode);
            xmlFreeNode(faultNode);
            return(NULL);
        }

        /* set faultactor node */
        xmlNodeSetContent(cur, faultActor);
    }

    return(faultNode);
}