提交 b79aaf91 编写于 作者: M Matthias Bolte

ESX: Don't automatically follow redirects.

The default transport for the VI API is HTTPS. If the server redirects
from HTTPS to HTTP the driver would silently follow that redirection.
The user assumes to communicate with the server over a secure transport
but isn't.

This patch disables automatical redirection following. The driver reports
an error if the server tries to redirect.

* src/esx/esx_vi.c: refactor the call to curl_easy_perform() into a
  function and do error handling there, disable automatical redirection
  following for curl
* src/esx/esx_vi.h: change the type of responseCode to int
上级 447ef886
......@@ -216,6 +216,68 @@ esxVI_CURL_Debug(CURL *curl ATTRIBUTE_UNUSED, curl_infotype type,
}
#endif
static int
esxVI_CURL_Perform(virConnectPtr conn, esxVI_Context *ctx, const char *url)
{
CURLcode errorCode;
long responseCode = 0;
#if LIBCURL_VERSION_NUM >= 0x071202 /* 7.18.2 */
const char *redirectUrl = NULL;
#endif
errorCode = curl_easy_perform(ctx->curl_handle);
if (errorCode != CURLE_OK) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"curl_easy_perform() returned an error: %s (%d)",
curl_easy_strerror(errorCode), errorCode);
return -1;
}
errorCode = curl_easy_getinfo(ctx->curl_handle, CURLINFO_RESPONSE_CODE,
&responseCode);
if (errorCode != CURLE_OK) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"curl_easy_getinfo(CURLINFO_RESPONSE_CODE) returned an "
"error: %s (%d)", curl_easy_strerror(errorCode),
errorCode);
return -1;
}
if (responseCode < 0) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"curl_easy_getinfo(CURLINFO_RESPONSE_CODE) returned a "
"negative response code");
return -1;
}
if (responseCode == 301) {
#if LIBCURL_VERSION_NUM >= 0x071202 /* 7.18.2 */
errorCode = curl_easy_getinfo(ctx->curl_handle, CURLINFO_REDIRECT_URL,
&redirectUrl);
if (errorCode != CURLE_OK) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"curl_easy_getinfo(CURLINFO_REDIRECT_URL) returned "
"an error: %s (%d)", curl_easy_strerror(errorCode),
errorCode);
} else {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"The server redirects from '%s' to '%s'", url,
redirectUrl);
}
#else
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"The server redirects from '%s'", url);
#endif
return -1;
}
return responseCode;
}
int
esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, const char *url,
const char *ipAddress, const char *username,
......@@ -269,7 +331,7 @@ esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, const char *url,
curl_easy_setopt(ctx->curl_handle, CURLOPT_URL, ctx->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, 1);
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_COOKIEFILE, "");
......@@ -433,8 +495,7 @@ esxVI_Context_DownloadFile(virConnectPtr conn, esxVI_Context *ctx,
const char *url, char **content)
{
virBuffer buffer = VIR_BUFFER_INITIALIZER;
CURLcode errorCode;
long responseCode;
int responseCode = 0;
if (content == NULL || *content != NULL) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
......@@ -448,27 +509,19 @@ esxVI_Context_DownloadFile(virConnectPtr conn, esxVI_Context *ctx,
curl_easy_setopt(ctx->curl_handle, CURLOPT_UPLOAD, 0);
curl_easy_setopt(ctx->curl_handle, CURLOPT_HTTPGET, 1);
errorCode = curl_easy_perform(ctx->curl_handle);
if (errorCode != CURLE_OK) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"curl_easy_perform() returned an error: %s (%d)",
curl_easy_strerror(errorCode), errorCode);
goto unlock;
}
responseCode = esxVI_CURL_Perform(conn, ctx, url);
errorCode = curl_easy_getinfo(ctx->curl_handle, CURLINFO_RESPONSE_CODE,
&responseCode);
virMutexUnlock(&ctx->curl_lock);
if (errorCode != CURLE_OK) {
if (responseCode < 0) {
goto failure;
} else if (responseCode != 200) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"curl_easy_getinfo() returned an error: %s (%d)",
curl_easy_strerror(errorCode), errorCode);
goto unlock;
"HTTP response code %d while trying to download '%s'",
responseCode, url);
goto failure;
}
virMutexUnlock(&ctx->curl_lock);
if (virBufferError(&buffer)) {
virReportOOMError(conn);
goto failure;
......@@ -476,32 +529,19 @@ esxVI_Context_DownloadFile(virConnectPtr conn, esxVI_Context *ctx,
*content = virBufferContentAndReset(&buffer);
if (responseCode != 200) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"HTTP response code %d while trying to download '%s'",
(int)responseCode, url);
goto failure;
}
return 0;
failure:
free(virBufferContentAndReset(&buffer));
return -1;
unlock:
virMutexUnlock(&ctx->curl_lock);
goto failure;
}
int
esxVI_Context_UploadFile(virConnectPtr conn, esxVI_Context *ctx,
const char *url, const char *content)
{
CURLcode errorCode;
long responseCode;
int responseCode = 0;
if (content == NULL) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
......@@ -515,40 +555,20 @@ esxVI_Context_UploadFile(virConnectPtr conn, esxVI_Context *ctx,
curl_easy_setopt(ctx->curl_handle, CURLOPT_UPLOAD, 1);
curl_easy_setopt(ctx->curl_handle, CURLOPT_INFILESIZE, strlen(content));
errorCode = curl_easy_perform(ctx->curl_handle);
if (errorCode != CURLE_OK) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"curl_easy_perform() returned an error: %s (%d)",
curl_easy_strerror(errorCode), errorCode);
goto unlock;
}
errorCode = curl_easy_getinfo(ctx->curl_handle, CURLINFO_RESPONSE_CODE,
&responseCode);
if (errorCode != CURLE_OK) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"curl_easy_getinfo() returned an error: %s (%d)",
curl_easy_strerror(errorCode), errorCode);
goto unlock;
}
responseCode = esxVI_CURL_Perform(conn, ctx, url);
virMutexUnlock(&ctx->curl_lock);
if (responseCode != 200 && responseCode != 201) {
if (responseCode < 0) {
return -1;
} else if (responseCode != 200 && responseCode != 201) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"HTTP response code %d while trying to upload to '%s'",
(int)responseCode, url);
responseCode, url);
return -1;
}
return 0;
unlock:
virMutexUnlock(&ctx->curl_lock);
return -1;
}
int
......@@ -558,7 +578,6 @@ esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx,
{
virBuffer buffer = VIR_BUFFER_INITIALIZER;
esxVI_Fault *fault = NULL;
CURLcode errorCode;
if (request == NULL || response == NULL || *response != NULL) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
......@@ -577,27 +596,14 @@ esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx,
curl_easy_setopt(ctx->curl_handle, CURLOPT_POSTFIELDS, request);
curl_easy_setopt(ctx->curl_handle, CURLOPT_POSTFIELDSIZE, strlen(request));
errorCode = curl_easy_perform(ctx->curl_handle);
if (errorCode != CURLE_OK) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"curl_easy_perform() returned an error: %s (%d)",
curl_easy_strerror(errorCode), errorCode);
goto unlock;
}
(*response)->responseCode = esxVI_CURL_Perform(conn, ctx, ctx->url);
errorCode = curl_easy_getinfo(ctx->curl_handle, CURLINFO_RESPONSE_CODE,
&(*response)->responseCode);
virMutexUnlock(&ctx->curl_lock);
if (errorCode != CURLE_OK) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"curl_easy_getinfo() returned an error: %s (%d)",
curl_easy_strerror(errorCode), errorCode);
goto unlock;
if ((*response)->responseCode < 0) {
goto failure;
}
virMutexUnlock(&ctx->curl_lock);
if (virBufferError(&buffer)) {
virReportOOMError(conn);
goto failure;
......@@ -695,8 +701,7 @@ esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx,
}
} else if ((*response)->responseCode != 200) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"HTTP response code %d", (int)(*response)->responseCode);
"HTTP response code %d", (*response)->responseCode);
goto failure;
}
......@@ -708,11 +713,6 @@ esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx,
esxVI_Fault_Free(&fault);
return -1;
unlock:
virMutexUnlock(&ctx->curl_lock);
goto failure;
}
......
......@@ -110,7 +110,7 @@ int esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx,
*/
struct _esxVI_Response {
long responseCode; /* required */
int responseCode; /* required */
char *content; /* required */
xmlDocPtr document; /* optional */
xmlXPathContextPtr xpathContext; /* optional */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册