Allow to specify a proxy to be used by libcurl. --- docs/drvesx.html.in | 20 ++++++++++++++++- src/esx/esx_driver.c | 12 +++++++--- src/esx/esx_util.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/esx/esx_util.h | 4 +++ src/esx/esx_vi.c | 17 ++++++++++++-- src/esx/esx_vi.h | 4 ++- 6 files changed, 105 insertions(+), 9 deletions(-) diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in index d454904..3c48c77 100644 --- a/docs/drvesx.html.in +++ b/docs/drvesx.html.in @@ -116,7 +116,25 @@ type://[username@]hostname[:port]/[?extraparameters] If set to 1, the driver answers all <a href="#questions">questions</a> with the default answer. If set to 0, questions are reported as errors. The default - value it 0. + value it 0. <span class="since">Since 0.7.5</span>. + </td> + </tr> + <tr> + <td> + <code>proxy</code> + </td> + <td> + <code>[type://]hostname[:port]</code> + </td> + <td> + Allows to specify a proxy for HTTP and HTTPS communication. + <span class="since">Since 0.8.2</span>. + The optional <code>type</code> part may be one of: + <code>http</code>, <code>socks</code>, <code>socks4</code>, + <code>socks4a</code> or <code>socks5</code>. The default is + <code>http</code> and <code>socks</code> is synonymous for + <code>socks5</code>. The optional <code>port</code> allows to + override the default port 1080. </td> </tr> </table> diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 0c12a31..3854f85 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -279,7 +279,7 @@ esxCapsInit(esxPrivate *priv) /* - * URI format: {esx|gsx}://[<user>@]<server>[:<port>]/[<query parameter> ...] + * URI format: {esx|gsx}://[<username>@]<hostname>[:<port>]/[<query parameter> ...] * * If no port is specified the default port is set dependent on the scheme and * transport parameter: @@ -293,6 +293,7 @@ esxCapsInit(esxPrivate *priv) * - vcenter={<vcenter>|*} * - no_verify={0|1} * - auto_answer={0|1} + * - proxy=[{http|socks|socks4|socks4a|socks5}://]<hostname>[:<port>] * * If no transport parameter is specified https is used. * @@ -308,6 +309,10 @@ esxCapsInit(esxPrivate *priv) * If the auto_answer parameter is set to 1, the driver will respond to all * virtual machine questions with the default answer, otherwise virtual machine * questions will be reported as errors. The default value it 0. + * + * The proxy parameter allows to specify a proxy for to be used by libcurl. + * The default for the optional <type> part is http and socks is synonymous for + * socks5. The optional <port> part allows to override the default port 1080. */ static virDrvOpenStatus esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) @@ -421,7 +426,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) if (esxVI_Context_Alloc(&priv->host) < 0 || esxVI_Context_Connect(priv->host, url, hostIpAddress, username, - password, parsedQuery->noVerify) < 0) { + password, parsedQuery) < 0) { goto cleanup; } @@ -554,8 +559,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) } if (esxVI_Context_Connect(priv->vCenter, url, vCenterIpAddress, - username, password, - parsedQuery->noVerify) < 0) { + username, password, parsedQuery) < 0) { goto cleanup; } diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c index dba9bc3..27c3a12 100644 --- a/src/esx/esx_util.c +++ b/src/esx/esx_util.c @@ -49,6 +49,7 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) int i; int noVerify; int autoAnswer; + char *tmp; if (parsedQuery == NULL || *parsedQuery != NULL) { ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument")); @@ -120,6 +121,61 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) } (*parsedQuery)->autoAnswer = autoAnswer != 0; + } else if (STRCASEEQ(queryParam->name, "proxy")) { + /* Expected format: [<type>://]<hostname>[:<port>] */ + (*parsedQuery)->proxy = true; + (*parsedQuery)->proxy_type = CURLPROXY_HTTP; + VIR_FREE((*parsedQuery)->proxy_hostname); + (*parsedQuery)->proxy_port = 1080; + + if ((tmp = STRSKIP(queryParam->value, "http://")) != NULL) { + (*parsedQuery)->proxy_type = CURLPROXY_HTTP; + } else if ((tmp = STRSKIP(queryParam->value, "socks://")) != NULL || + (tmp = STRSKIP(queryParam->value, "socks5://")) != NULL) { + (*parsedQuery)->proxy_type = CURLPROXY_SOCKS5; + } else if ((tmp = STRSKIP(queryParam->value, "socks4://")) != NULL) { + (*parsedQuery)->proxy_type = CURLPROXY_SOCKS4; + } else if ((tmp = STRSKIP(queryParam->value, "socks4a://")) != NULL) { + (*parsedQuery)->proxy_type = CURLPROXY_SOCKS4A; + } else if ((tmp = strstr(queryParam->value, "://")) != NULL) { + *tmp = '\0'; + + ESX_ERROR(VIR_ERR_INVALID_ARG, + _("Query parameter 'proxy' contains unexpected " + "type '%s' (should be (http|socks(|4|4a|5))"), + queryParam->value); + goto cleanup; + } else { + tmp = queryParam->value; + } + + (*parsedQuery)->proxy_hostname = strdup(tmp); + + if ((*parsedQuery)->proxy_hostname == NULL) { + virReportOOMError(); + goto cleanup; + } + + if ((tmp = strchr((*parsedQuery)->proxy_hostname, ':')) != NULL) { + if (tmp == (*parsedQuery)->proxy_hostname) { + ESX_ERROR(VIR_ERR_INVALID_ARG, "%s", + _("Query parameter 'proxy' doesn't contain a " + "hostname")); + goto cleanup; + } + + *tmp++ = '\0'; + + if (virStrToLong_i(tmp, NULL, 10, + &(*parsedQuery)->proxy_port) < 0 || + (*parsedQuery)->proxy_port < 1 || + (*parsedQuery)->proxy_port > 65535) { + ESX_ERROR(VIR_ERR_INVALID_ARG, + _("Query parameter 'proxy' has unexpected port" + "value '%s' (should be [1..65535])"), tmp); + goto cleanup; + } + } } else { VIR_WARN("Ignoring unexpected query parameter '%s'", queryParam->name); @@ -161,6 +217,7 @@ esxUtil_FreeParsedQuery(esxUtil_ParsedQuery **parsedQuery) VIR_FREE((*parsedQuery)->transport); VIR_FREE((*parsedQuery)->vCenter); + VIR_FREE((*parsedQuery)->proxy_hostname); VIR_FREE(*parsedQuery); } diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h index ae6e38b..26c456d 100644 --- a/src/esx/esx_util.h +++ b/src/esx/esx_util.h @@ -36,6 +36,10 @@ struct _esxUtil_ParsedQuery { char *vCenter; bool noVerify; bool autoAnswer; + bool proxy; + int proxy_type; + char *proxy_hostname; + int proxy_port; }; int esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri); diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index 4332f2b..8c43d67 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -277,7 +277,7 @@ esxVI_CURL_Perform(esxVI_Context *ctx, const char *url) int esxVI_Context_Connect(esxVI_Context *ctx, const char *url, const char *ipAddress, const char *username, - const char *password, bool noVerify) + const char *password, esxUtil_ParsedQuery *parsedQuery) { int result = -1; esxVI_String *propertyNameList = NULL; @@ -328,8 +328,10 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url, curl_easy_setopt(ctx->curl_handle, CURLOPT_USERAGENT, "libvirt-esx"); curl_easy_setopt(ctx->curl_handle, CURLOPT_HEADER, 0); curl_easy_setopt(ctx->curl_handle, CURLOPT_FOLLOWLOCATION, 0); - curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYPEER, noVerify ? 0 : 1); - curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYHOST, noVerify ? 0 : 2); + curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYPEER, + parsedQuery->noVerify ? 0 : 1); + curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYHOST, + parsedQuery->noVerify ? 0 : 2); curl_easy_setopt(ctx->curl_handle, CURLOPT_COOKIEFILE, ""); curl_easy_setopt(ctx->curl_handle, CURLOPT_HTTPHEADER, ctx->curl_headers); curl_easy_setopt(ctx->curl_handle, CURLOPT_READFUNCTION, @@ -343,6 +345,15 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url, curl_easy_setopt(ctx->curl_handle, CURLOPT_VERBOSE, 1); #endif + if (parsedQuery->proxy) { + curl_easy_setopt(ctx->curl_handle, CURLOPT_PROXY, + parsedQuery->proxy_hostname); + curl_easy_setopt(ctx->curl_handle, CURLOPT_PROXYTYPE, + parsedQuery->proxy_type); + curl_easy_setopt(ctx->curl_handle, CURLOPT_PROXYPORT, + parsedQuery->proxy_port); + } + if (virMutexInit(&ctx->curl_lock) < 0) { ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not initialize CURL mutex")); diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h index 521be0c..f5e89e9 100644 --- a/src/esx/esx_vi.h +++ b/src/esx/esx_vi.h @@ -31,6 +31,7 @@ # include "virterror_internal.h" # include "datatypes.h" # include "esx_vi_types.h" +# include "esx_util.h" @@ -161,7 +162,8 @@ int esxVI_Context_Alloc(esxVI_Context **ctx); void esxVI_Context_Free(esxVI_Context **ctx); int esxVI_Context_Connect(esxVI_Context *ctx, const char *ipAddress, const char *url, const char *username, - const char *password, bool noVerify); + const char *password, + esxUtil_ParsedQuery *parsedQuery); int esxVI_Context_DownloadFile(esxVI_Context *ctx, const char *url, char **content); int esxVI_Context_UploadFile(esxVI_Context *ctx, const char *url, -- 1.7.0.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list