From: Dmitry Stogov Date: Mon, 17 Aug 2009 18:23:48 +0000 (+0000) Subject: Fixed bug #49144 (import of schema from different host transmits original authenticat... X-Git-Tag: php-5.4.0alpha1~191^2~2790 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5fea6def7684388a1fae18d221b35461ae7cec80;p=php Fixed bug #49144 (import of schema from different host transmits original authentication details) --- diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index a4d2680c88..64e1ea6627 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -102,7 +102,10 @@ static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlA xmlNodePtr schema; xmlAttrPtr new_tns; + sdl_set_uri_credentials(ctx, (char*)location TSRMLS_CC); doc = soap_xmlParseFile((char*)location TSRMLS_CC); + sdl_restore_uri_credentials(ctx TSRMLS_CC); + if (doc == NULL) { soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s'", location); } diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index fb0d8b8426..d1d25e8900 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -226,6 +226,64 @@ static int is_wsdl_element(xmlNodePtr node) return 1; } +void sdl_set_uri_credentials(sdlCtx *ctx, char *uri TSRMLS_DC) +{ + char *s; + int l1, l2; + zval *context = NULL; + zval **header = NULL; + + /* check if we load xsd from the same server */ + s = strstr(ctx->sdl->source, "://"); + if (!s) return; + s = strchr(s+3, '/'); + l1 = s - ctx->sdl->source; + s = strstr((char*)uri, "://"); + if (!s) return; + s = strchr(s+3, '/'); + l2 = s - (char*)uri; + if (l1 != l2 || memcmp(ctx->sdl->source, uri, l1) != 0) { + /* another server. clear authentication credentals */ + context = php_libxml_switch_context(NULL TSRMLS_CC); + php_libxml_switch_context(context TSRMLS_CC); + if (context) { + ctx->context = php_stream_context_from_zval(context, 1); + + if (ctx->context && + php_stream_context_get_option(ctx->context, "http", "header", &header) == SUCCESS) { + s = strstr(Z_STRVAL_PP(header), "Authorization: Basic"); + if (s && (s == Z_STRVAL_PP(header) || *(s-1) == '\n' || *(s-1) == '\r')) { + char *rest = strstr(s, "\r\n"); + if (rest) { + zval new_header; + + rest += 2; + Z_TYPE(new_header) = IS_STRING; + Z_STRLEN(new_header) = Z_STRLEN_PP(header) - (rest - s); + Z_STRVAL(new_header) = emalloc(Z_STRLEN_PP(header) + 1); + memcpy(Z_STRVAL(new_header), Z_STRVAL_PP(header), s - Z_STRVAL_PP(header)); + memcpy(Z_STRVAL(new_header) + (s - Z_STRVAL_PP(header)), rest, Z_STRLEN_PP(header) - (rest - Z_STRVAL_PP(header)) + 1); + ctx->old_header = *header; + Z_ADDREF_P(ctx->old_header); + php_stream_context_set_option(ctx->context, "http", "header", &new_header); + zval_dtor(&new_header); + } + } + } + } + } +} + +void sdl_restore_uri_credentials(sdlCtx *ctx TSRMLS_DC) +{ + if (ctx->old_header) { + php_stream_context_set_option(ctx->context, "http", "header", ctx->old_header); + zval_ptr_dtor(&ctx->old_header); + ctx->old_header = NULL; + } + ctx->context = NULL; +} + static void load_wsdl_ex(char *struri, sdlCtx *ctx, int include TSRMLS_DC) { sdlPtr tmpsdl = ctx->sdl; @@ -237,7 +295,9 @@ static void load_wsdl_ex(char *struri, sdlCtx *ctx, int include TSRMLS_DC) return; } + sdl_set_uri_credentials(ctx, struri TSRMLS_CC); wsdl = soap_xmlParseFile(struri TSRMLS_CC); + sdl_restore_uri_credentials(ctx TSRMLS_CC); if (!wsdl) { xmlErrorPtr xmlErrorPtr = xmlGetLastError(); diff --git a/ext/soap/php_sdl.h b/ext/soap/php_sdl.h index 53f6fb088e..e9554812dc 100644 --- a/ext/soap/php_sdl.h +++ b/ext/soap/php_sdl.h @@ -76,6 +76,8 @@ typedef struct sdlCtx { HashTable *attributes; /* array of sdlAttributePtr */ HashTable *attributeGroups; /* array of sdlTypesPtr */ + php_stream_context *context; + zval *old_header; } sdlCtx; struct _sdlBinding { @@ -264,4 +266,7 @@ sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns); void delete_sdl(void *handle); void delete_sdl_impl(void *handle); +void sdl_set_uri_credentials(sdlCtx *ctx, char *uri TSRMLS_DC); +void sdl_restore_uri_credentials(sdlCtx *ctx TSRMLS_DC); + #endif