diff options
author | Anas Nashif <anas.nashif@intel.com> | 2013-09-20 04:45:41 -0400 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2013-09-20 04:45:41 -0400 |
commit | 6b6383d52bc147134bb6b60b07e924b176c67e3a (patch) | |
tree | 9753a1ec40b1fbe2acfaa881af46e3c0f7da6401 /src/xslt.c | |
parent | 07bb297329b9e9754d09dcb6d70417272a626619 (diff) | |
download | xmlsec1-6b6383d52bc147134bb6b60b07e924b176c67e3a.tar.gz xmlsec1-6b6383d52bc147134bb6b60b07e924b176c67e3a.tar.bz2 xmlsec1-6b6383d52bc147134bb6b60b07e924b176c67e3a.zip |
Imported Upstream version 1.2.19
Diffstat (limited to 'src/xslt.c')
-rw-r--r-- | src/xslt.c | 695 |
1 files changed, 397 insertions, 298 deletions
@@ -1,11 +1,11 @@ -/** +/** * XML Security Library (http://www.aleksey.com/xmlsec). * * XSLT Transform (http://www.w3.org/TR/xmldsig-core/#sec-XSLT) * * This is free software; see Copyright file in the source * distribution for preciese wording. - * + * * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> */ #include "globals.h" @@ -14,7 +14,7 @@ #include <stdlib.h> #include <string.h> - + #include <libxml/tree.h> #include <libxslt/xslt.h> #include <libxslt/xsltInternals.h> @@ -28,122 +28,173 @@ #include <xmlsec/keys.h> #include <xmlsec/parser.h> #include <xmlsec/errors.h> +#include <xmlsec/private/xslt.h> /************************************************************************** * * Internal xslt ctx * *****************************************************************************/ -typedef struct _xmlSecXsltCtx xmlSecXsltCtx, *xmlSecXsltCtxPtr; +typedef struct _xmlSecXsltCtx xmlSecXsltCtx, *xmlSecXsltCtxPtr; struct _xmlSecXsltCtx { - xsltStylesheetPtr xslt; - xmlParserCtxtPtr parserCtx; -}; + xsltStylesheetPtr xslt; + xmlParserCtxtPtr parserCtx; +}; /**************************************************************************** * * XSLT transform * * xmlSecXsltCtx is located after xmlSecTransform - * + * ***************************************************************************/ -#define xmlSecXsltSize \ - (sizeof(xmlSecTransform) + sizeof(xmlSecXsltCtx)) +#define xmlSecXsltSize \ + (sizeof(xmlSecTransform) + sizeof(xmlSecXsltCtx)) #define xmlSecXsltGetCtx(transform) \ ((xmlSecXsltCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform))) -static int xmlSecXsltInitialize (xmlSecTransformPtr transform); -static void xmlSecXsltFinalize (xmlSecTransformPtr transform); -static int xmlSecXsltReadNode (xmlSecTransformPtr transform, - xmlNodePtr node, - xmlSecTransformCtxPtr transformCtx); -static int xmlSecXsltPushBin (xmlSecTransformPtr transform, - const xmlSecByte* data, - xmlSecSize dataSize, - int final, - xmlSecTransformCtxPtr transformCtx); -static int xmlSecXsltExecute (xmlSecTransformPtr transform, - int last, - xmlSecTransformCtxPtr transformCtx); -static int xmlSecXslProcess (xmlSecBufferPtr in, - xmlSecBufferPtr out, - xsltStylesheetPtr stylesheet); +static int xmlSecXsltInitialize (xmlSecTransformPtr transform); +static void xmlSecXsltFinalize (xmlSecTransformPtr transform); +static int xmlSecXsltReadNode (xmlSecTransformPtr transform, + xmlNodePtr node, + xmlSecTransformCtxPtr transformCtx); +static int xmlSecXsltPushBin (xmlSecTransformPtr transform, + const xmlSecByte* data, + xmlSecSize dataSize, + int final, + xmlSecTransformCtxPtr transformCtx); +static int xmlSecXsltExecute (xmlSecTransformPtr transform, + int last, + xmlSecTransformCtxPtr transformCtx); +static int xmlSecXslProcess (xmlSecXsltCtxPtr ctx, + xmlSecBufferPtr in, + xmlSecBufferPtr out); +static xmlDocPtr xmlSecXsApplyStylesheet (xmlSecXsltCtxPtr ctx, + xmlDocPtr doc); + static xmlSecTransformKlass xmlSecXsltKlass = { /* klass/object sizes */ - sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ - xmlSecXsltSize, /* xmlSecSize objSize */ - - xmlSecNameXslt, /* const xmlChar* name; */ - xmlSecHrefXslt, /* const xmlChar* href; */ - xmlSecTransformUsageDSigTransform, /* xmlSecAlgorithmUsage usage; */ - - xmlSecXsltInitialize, /* xmlSecTransformInitializeMethod initialize; */ - xmlSecXsltFinalize, /* xmlSecTransformFinalizeMethod finalize; */ - xmlSecXsltReadNode, /* xmlSecTransformNodeReadMethod readNode; */ - NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ - NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */ - NULL, /* xmlSecTransformSetKeyMethod setKey; */ - NULL, /* xmlSecTransformValidateMethod validate; */ - xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ - xmlSecXsltPushBin, /* xmlSecTransformPushBinMethod pushBin; */ - xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ - NULL, /* xmlSecTransformPushXmlMethod pushXml; */ - NULL, /* xmlSecTransformPopXmlMethod popXml; */ - xmlSecXsltExecute, /* xmlSecTransformExecuteMethod execute; */ - - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ + sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ + xmlSecXsltSize, /* xmlSecSize objSize */ + + xmlSecNameXslt, /* const xmlChar* name; */ + xmlSecHrefXslt, /* const xmlChar* href; */ + xmlSecTransformUsageDSigTransform, /* xmlSecAlgorithmUsage usage; */ + + xmlSecXsltInitialize, /* xmlSecTransformInitializeMethod initialize; */ + xmlSecXsltFinalize, /* xmlSecTransformFinalizeMethod finalize; */ + xmlSecXsltReadNode, /* xmlSecTransformNodeReadMethod readNode; */ + NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ + NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */ + NULL, /* xmlSecTransformSetKeyMethod setKey; */ + NULL, /* xmlSecTransformValidateMethod validate; */ + xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ + xmlSecXsltPushBin, /* xmlSecTransformPushBinMethod pushBin; */ + xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ + NULL, /* xmlSecTransformPushXmlMethod pushXml; */ + NULL, /* xmlSecTransformPopXmlMethod popXml; */ + xmlSecXsltExecute, /* xmlSecTransformExecuteMethod execute; */ + + NULL, /* void* reserved0; */ + NULL, /* void* reserved1; */ }; + +#define XMLSEC_XSLT_COPY_SEC_PREF(src, dst, pref) \ + xsltSetSecurityPrefs((dst), (pref), xsltGetSecurityPrefs((src), (pref))) + +static xsltSecurityPrefsPtr g_xslt_default_security_prefs = NULL; + +void xmlSecTransformXsltInitialize(void) { + xmlSecAssert(g_xslt_default_security_prefs == NULL); + + g_xslt_default_security_prefs = xsltNewSecurityPrefs(); + xmlSecAssert(g_xslt_default_security_prefs != NULL); + xsltSetSecurityPrefs(g_xslt_default_security_prefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid); + xsltSetSecurityPrefs(g_xslt_default_security_prefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid); + xsltSetSecurityPrefs(g_xslt_default_security_prefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid); + xsltSetSecurityPrefs(g_xslt_default_security_prefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid); + xsltSetSecurityPrefs(g_xslt_default_security_prefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid); +} + +void xmlSecTransformXsltShutdown(void) { + if(g_xslt_default_security_prefs != NULL) { + xsltFreeSecurityPrefs(g_xslt_default_security_prefs); + g_xslt_default_security_prefs = NULL; + } +} + +/** + * xmlSecTransformXsltSetDefaultSecurityPrefs: + * @sec: the new security preferences + * + * Sets the new default security preferences. The xmlsec default security policy is + * to disable everything. + */ +XMLSEC_EXPORT void +xmlSecTransformXsltSetDefaultSecurityPrefs(xsltSecurityPrefsPtr sec) { + xmlSecAssert(sec != NULL); + xmlSecAssert(g_xslt_default_security_prefs != NULL); + + /* copy prefs */ + XMLSEC_XSLT_COPY_SEC_PREF(sec, g_xslt_default_security_prefs, XSLT_SECPREF_READ_FILE); + XMLSEC_XSLT_COPY_SEC_PREF(sec, g_xslt_default_security_prefs, XSLT_SECPREF_WRITE_FILE); + XMLSEC_XSLT_COPY_SEC_PREF(sec, g_xslt_default_security_prefs, XSLT_SECPREF_CREATE_DIRECTORY); + XMLSEC_XSLT_COPY_SEC_PREF(sec, g_xslt_default_security_prefs, XSLT_SECPREF_READ_NETWORK); + XMLSEC_XSLT_COPY_SEC_PREF(sec, g_xslt_default_security_prefs, XSLT_SECPREF_WRITE_NETWORK); +} + /** * xmlSecTransformXsltGetKlass: * * XSLT transform klass (http://www.w3.org/TR/xmldsig-core/#sec-XSLT): * - * The normative specification for XSL Transformations is [XSLT]. - * Specification of a namespace-qualified stylesheet element, which MUST be - * the sole child of the Transform element, indicates that the specified style - * sheet should be used. Whether this instantiates in-line processing of local - * XSLT declarations within the resource is determined by the XSLT processing - * model; the ordered application of multiple stylesheet may require multiple - * Transforms. No special provision is made for the identification of a remote - * stylesheet at a given URI because it can be communicated via an xsl:include + * The normative specification for XSL Transformations is [XSLT]. + * Specification of a namespace-qualified stylesheet element, which MUST be + * the sole child of the Transform element, indicates that the specified style + * sheet should be used. Whether this instantiates in-line processing of local + * XSLT declarations within the resource is determined by the XSLT processing + * model; the ordered application of multiple stylesheet may require multiple + * Transforms. No special provision is made for the identification of a remote + * stylesheet at a given URI because it can be communicated via an xsl:include * or xsl:import within the stylesheet child of the Transform. * - * This transform requires an octet stream as input. If the actual input is an - * XPath node-set, then the signature application should attempt to convert it - * to octets (apply Canonical XML]) as described in the Reference Processing + * This transform requires an octet stream as input. If the actual input is an + * XPath node-set, then the signature application should attempt to convert it + * to octets (apply Canonical XML]) as described in the Reference Processing * Model (section 4.3.3.2).] * - * The output of this transform is an octet stream. The processing rules for + * The output of this transform is an octet stream. The processing rules for * the XSL style sheet or transform element are stated in the XSLT specification - * [XSLT]. We RECOMMEND that XSLT transform authors use an output method of xml - * for XML and HTML. As XSLT implementations do not produce consistent - * serializations of their output, we further RECOMMEND inserting a transform - * after the XSLT transform to canonicalize the output. These steps will help - * to ensure interoperability of the resulting signatures among applications - * that support the XSLT transform. Note that if the output is actually HTML, + * [XSLT]. We RECOMMEND that XSLT transform authors use an output method of xml + * for XML and HTML. As XSLT implementations do not produce consistent + * serializations of their output, we further RECOMMEND inserting a transform + * after the XSLT transform to canonicalize the output. These steps will help + * to ensure interoperability of the resulting signatures among applications + * that support the XSLT transform. Note that if the output is actually HTML, * then the result of these steps is logically equivalent [XHTML]. * * Returns: pointer to XSLT transform klass. */ -xmlSecTransformId +xmlSecTransformId xmlSecTransformXsltGetKlass(void) { return(&xmlSecXsltKlass); } - -static int -xmlSecXsltInitialize(xmlSecTransformPtr transform) { + +static int +xmlSecXsltInitialize(xmlSecTransformPtr transform) { xmlSecXsltCtxPtr ctx; - + xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXsltId), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecXsltSize), -1); ctx = xmlSecXsltGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); - + /* initialize context */ memset(ctx, 0, sizeof(xmlSecXsltCtx)); + + /* done */ return(0); } @@ -156,12 +207,12 @@ xmlSecXsltFinalize(xmlSecTransformPtr transform) { ctx = xmlSecXsltGetCtx(transform); xmlSecAssert(ctx != NULL); - + if(ctx->xslt != NULL) { - xsltFreeStylesheet(ctx->xslt); + xsltFreeStylesheet(ctx->xslt); } if(ctx->parserCtx != NULL) { - xmlFreeParserCtxt(ctx->parserCtx); + xmlFreeParserCtxt(ctx->parserCtx); } memset(ctx, 0, sizeof(xmlSecXsltCtx)); } @@ -172,70 +223,70 @@ xmlSecXsltReadNode(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransfor xmlBufferPtr buffer; xmlDocPtr doc; xmlNodePtr cur; - + xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXsltId), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecXsltSize), -1); - xmlSecAssert2(node != NULL, -1); - xmlSecAssert2(transformCtx != NULL, -1); + xmlSecAssert2(node != NULL, -1); + xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecXsltGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->xslt == NULL, -1); - /* read content in the buffer */ + /* read content in the buffer */ buffer = xmlBufferCreate(); if(buffer == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlBufferCreate", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xmlBufferCreate", + XMLSEC_ERRORS_R_XML_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } cur = node->children; while(cur != NULL) { - xmlNodeDump(buffer, cur->doc, cur, 0, 0); - cur = cur->next; + xmlNodeDump(buffer, cur->doc, cur, 0, 0); + cur = cur->next; } - + /* parse the buffer */ - doc = xmlSecParseMemory(xmlBufferContent(buffer), - xmlBufferLength(buffer), 1); + doc = xmlSecParseMemory(xmlBufferContent(buffer), + xmlBufferLength(buffer), 1); if(doc == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecParseMemory", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlBufferFree(buffer); - return(-1); + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xmlSecParseMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlBufferFree(buffer); + return(-1); } - /* pre-process stylesheet */ + /* pre-process stylesheet */ ctx->xslt = xsltParseStylesheetDoc(doc); if(ctx->xslt == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xsltParseStylesheetDoc", - XMLSEC_ERRORS_R_XSLT_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - /* after parsing stylesheet doc is assigned - * to it and will be freed by xsltFreeStylesheet() */ - xmlFreeDoc(doc); - xmlBufferFree(buffer); - return(-1); + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xsltParseStylesheetDoc", + XMLSEC_ERRORS_R_XSLT_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + /* after parsing stylesheet doc is assigned + * to it and will be freed by xsltFreeStylesheet() */ + xmlFreeDoc(doc); + xmlBufferFree(buffer); + return(-1); } - + xmlBufferFree(buffer); return(0); } -static int +static int xmlSecXsltPushBin(xmlSecTransformPtr transform, const xmlSecByte* data, - xmlSecSize dataSize, int final, xmlSecTransformCtxPtr transformCtx) { + xmlSecSize dataSize, int final, xmlSecTransformCtxPtr transformCtx) { xmlSecXsltCtxPtr ctx; int ret; - + xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXsltId), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecXsltSize), -1); xmlSecAssert2(transformCtx != NULL, -1); @@ -246,136 +297,136 @@ xmlSecXsltPushBin(xmlSecTransformPtr transform, const xmlSecByte* data, /* check/update current transform status */ if(transform->status == xmlSecTransformStatusNone) { - xmlSecAssert2(ctx->parserCtx == NULL, -1); - - ctx->parserCtx = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL); - if(ctx->parserCtx == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlCreatePushParserCtxt", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } + xmlSecAssert2(ctx->parserCtx == NULL, -1); + + ctx->parserCtx = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL); + if(ctx->parserCtx == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xmlCreatePushParserCtxt", + XMLSEC_ERRORS_R_XML_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } /* required for c14n! */ - ctx->parserCtx->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS; - ctx->parserCtx->replaceEntities = 1; + ctx->parserCtx->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS; + ctx->parserCtx->replaceEntities = 1; - transform->status = xmlSecTransformStatusWorking; + transform->status = xmlSecTransformStatusWorking; } else if(transform->status == xmlSecTransformStatusFinished) { - return(0); + return(0); } else if(transform->status != xmlSecTransformStatusWorking) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_STATUS, - "status=%d", transform->status); - return(-1); + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + NULL, + XMLSEC_ERRORS_R_INVALID_STATUS, + "status=%d", transform->status); + return(-1); } xmlSecAssert2(transform->status == xmlSecTransformStatusWorking, -1); xmlSecAssert2(ctx->parserCtx != NULL, -1); - + /* push data to the input buffer */ if((data != NULL) && (dataSize > 0)) { - ret = xmlParseChunk(ctx->parserCtx, (const char*)data, dataSize, 0); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlParseChunk", - XMLSEC_ERRORS_R_XML_FAILED, - "size=%d", dataSize); - return(-1); - } - } - + ret = xmlParseChunk(ctx->parserCtx, (const char*)data, dataSize, 0); + if(ret != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xmlParseChunk", + XMLSEC_ERRORS_R_XML_FAILED, + "size=%d", dataSize); + return(-1); + } + } + /* finish parsing, apply xslt transforms and push to next in the chain */ if(final != 0) { xmlDocPtr docIn; xmlDocPtr docOut; xmlOutputBufferPtr output; - /* finalize */ - ret = xmlParseChunk(ctx->parserCtx, NULL, 0, 1); - if((ret != 0) || (ctx->parserCtx->myDoc == NULL)) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlParseChunk", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - - /* todo: check that document is well formed? */ - docIn = ctx->parserCtx->myDoc; - ctx->parserCtx->myDoc = NULL; - - docOut = xsltApplyStylesheet(ctx->xslt, docIn, NULL); - if(docOut == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xsltApplyStylesheet", - XMLSEC_ERRORS_R_XSLT_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlFreeDoc(docIn); - return(-1); - } - xmlFreeDoc(docIn); - - if(transform->next != NULL) { - output = xmlSecTransformCreateOutputBuffer(transform->next, transformCtx); - if(output == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecTransformCreateOutputBuffer", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlFreeDoc(docOut); - return(-1); - } - } else { - output = xmlSecBufferCreateOutputBuffer(&(transform->outBuf)); - if(output == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecBufferCreateOutputBuffer", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlFreeDoc(docOut); - return(-1); - } - } - - ret = xsltSaveResultTo(output, docOut, ctx->xslt); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xsltSaveResultTo", - XMLSEC_ERRORS_R_XSLT_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlOutputBufferClose(output); - xmlFreeDoc(docOut); - return(-1); - } - ret = xmlOutputBufferClose(output); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlOutputBufferClose", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlFreeDoc(docOut); - return(-1); - } - xmlFreeDoc(docOut); - - transform->status = xmlSecTransformStatusFinished; + /* finalize */ + ret = xmlParseChunk(ctx->parserCtx, NULL, 0, 1); + if((ret != 0) || (ctx->parserCtx->myDoc == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xmlParseChunk", + XMLSEC_ERRORS_R_XML_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + /* todo: check that document is well formed? */ + docIn = ctx->parserCtx->myDoc; + ctx->parserCtx->myDoc = NULL; + + docOut = xmlSecXsApplyStylesheet(ctx, docIn); + if(docOut == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xmlSecXsApplyStylesheet", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFreeDoc(docIn); + return(-1); + } + xmlFreeDoc(docIn); + + if(transform->next != NULL) { + output = xmlSecTransformCreateOutputBuffer(transform->next, transformCtx); + if(output == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xmlSecTransformCreateOutputBuffer", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFreeDoc(docOut); + return(-1); + } + } else { + output = xmlSecBufferCreateOutputBuffer(&(transform->outBuf)); + if(output == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xmlSecBufferCreateOutputBuffer", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFreeDoc(docOut); + return(-1); + } + } + + ret = xsltSaveResultTo(output, docOut, ctx->xslt); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xsltSaveResultTo", + XMLSEC_ERRORS_R_XSLT_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlOutputBufferClose(output); + xmlFreeDoc(docOut); + return(-1); + } + ret = xmlOutputBufferClose(output); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xmlOutputBufferClose", + XMLSEC_ERRORS_R_XML_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFreeDoc(docOut); + return(-1); + } + xmlFreeDoc(docOut); + + transform->status = xmlSecTransformStatusFinished; } return(0); } -static int +static int xmlSecXsltExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecXsltCtxPtr ctx; xmlSecBufferPtr in, out; @@ -393,57 +444,57 @@ xmlSecXsltExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr in = &(transform->inBuf); out = &(transform->outBuf); inSize = xmlSecBufferGetSize(in); - outSize = xmlSecBufferGetSize(out); - + outSize = xmlSecBufferGetSize(out); + if(transform->status == xmlSecTransformStatusNone) { - transform->status = xmlSecTransformStatusWorking; - } - + transform->status = xmlSecTransformStatusWorking; + } + if((transform->status == xmlSecTransformStatusWorking) && (last == 0)) { - /* just do nothing */ - xmlSecAssert2(outSize == 0, -1); + /* just do nothing */ + xmlSecAssert2(outSize == 0, -1); } else if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) { - xmlSecAssert2(outSize == 0, -1); - - ret = xmlSecXslProcess(in, out, ctx->xslt); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecXslProcess", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - - ret = xmlSecBufferRemoveHead(in, inSize); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecBufferRemoveHead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", inSize); - return(-1); - } - - transform->status = xmlSecTransformStatusFinished; + xmlSecAssert2(outSize == 0, -1); + + ret = xmlSecXslProcess(ctx, in, out); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xmlSecXslProcess", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecBufferRemoveHead(in, inSize); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + "xmlSecBufferRemoveHead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "size=%d", inSize); + return(-1); + } + + transform->status = xmlSecTransformStatusFinished; } else if(transform->status == xmlSecTransformStatusFinished) { - /* the only way we can get here is if there is no input */ - xmlSecAssert2(inSize == 0, -1); + /* the only way we can get here is if there is no input */ + xmlSecAssert2(inSize == 0, -1); } else { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_STATUS, - "status=%d", transform->status); - return(-1); + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), + NULL, + XMLSEC_ERRORS_R_INVALID_STATUS, + "status=%d", transform->status); + return(-1); } return(0); } /* TODO: create PopBin method instead */ -static int -xmlSecXslProcess(xmlSecBufferPtr in, xmlSecBufferPtr out, xsltStylesheetPtr stylesheet) { +static int +xmlSecXslProcess(xmlSecXsltCtxPtr ctx, xmlSecBufferPtr in, xmlSecBufferPtr out) { xmlDocPtr docIn = NULL; xmlDocPtr docOut = NULL; xmlOutputBufferPtr output = NULL; @@ -452,67 +503,115 @@ xmlSecXslProcess(xmlSecBufferPtr in, xmlSecBufferPtr out, xsltStylesheetPtr sty xmlSecAssert2(in != NULL, -1); xmlSecAssert2(out != NULL, -1); - xmlSecAssert2(stylesheet != NULL, -1); + xmlSecAssert2(ctx != NULL, -1); docIn = xmlSecParseMemory(xmlSecBufferGetData(in), xmlSecBufferGetSize(in), 1); if(docIn == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecParseMemory", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - goto done; + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecParseMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; } - docOut = xsltApplyStylesheet(stylesheet, docIn, NULL); + docOut = xmlSecXsApplyStylesheet(ctx, docIn); if(docOut == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xsltApplyStylesheet", - XMLSEC_ERRORS_R_XSLT_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - goto done; + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecXsApplyStylesheet", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; } output = xmlSecBufferCreateOutputBuffer(out); if(output == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecBufferCreateOutputBuffer", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - goto done; + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferCreateOutputBuffer", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; } - ret = xsltSaveResultTo(output, docOut, stylesheet); + ret = xsltSaveResultTo(output, docOut, ctx->xslt); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xsltSaveResultTo", - XMLSEC_ERRORS_R_XSLT_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - goto done; + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xsltSaveResultTo", + XMLSEC_ERRORS_R_XSLT_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; } ret = xmlOutputBufferClose(output); output = NULL; if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlOutputBufferClose", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlOutputBufferClose", + XMLSEC_ERRORS_R_XML_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); } res = 0; -done: +done: if(output != NULL) xmlOutputBufferClose(output); if(docIn != NULL) xmlFreeDoc(docIn); if(docOut != NULL) xmlFreeDoc(docOut); - return(res); + return(res); +} + + +static xmlDocPtr +xmlSecXsApplyStylesheet(xmlSecXsltCtxPtr ctx, xmlDocPtr doc) { + xsltTransformContextPtr xsltCtx = NULL; + xmlDocPtr res = NULL; + int ret; + + xmlSecAssert2(ctx != NULL, NULL); + xmlSecAssert2(ctx->xslt != NULL, NULL); + xmlSecAssert2(doc != NULL, NULL); + + xsltCtx = xsltNewTransformContext(ctx->xslt, doc); + if(xsltCtx == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xsltNewTransformContext", + XMLSEC_ERRORS_R_XSLT_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* set security prefs */ + ret = xsltSetCtxtSecurityPrefs(g_xslt_default_security_prefs, xsltCtx); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xsltSetCtxtSecurityPrefs", + XMLSEC_ERRORS_R_XSLT_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + res = xsltApplyStylesheetUser(ctx->xslt, doc, NULL, NULL, NULL, xsltCtx); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xsltApplyStylesheetUser", + XMLSEC_ERRORS_R_XSLT_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + +done: + if(xsltCtx != NULL) xsltFreeTransformContext(xsltCtx); + return res; } + #endif /* XMLSEC_NO_XSLT */ |