]> xenbits.xensource.com Git - libvirt.git/commitdiff
esx: do not store escaped password in esxVI_Context.
authorDawid Zamirski <dzamirski@datto.com>
Thu, 26 May 2016 15:30:11 +0000 (11:30 -0400)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 26 May 2016 16:27:55 +0000 (18:27 +0200)
This patch fixes an issue where screenshot API call was failing when
the esx/vcenter password contains special characters such as
apostrophee. The reason for failures was that passwords were escaped
for XML and stored in esxVI_Context which was then passed to raw CURL
API calls where the password must be passed in original form to
authenticate successfully. So this patch addresses this by storing
original passwords in the esxVI_Context struct and escape only for
esxVI_Login call.

src/esx/esx_driver.c
src/esx/esx_vi.c

index 00d0e0a6f04f342c824d1e8e1bbc6eb625a12395..031c666f620d96debe8f5740e3e04a895d2e16df 100644 (file)
@@ -617,7 +617,6 @@ esxConnectToHost(esxPrivate *priv,
     int result = -1;
     char ipAddress[NI_MAXHOST] = "";
     char *username = NULL;
-    char *unescapedPassword = NULL;
     char *password = NULL;
     char *url = NULL;
     esxVI_String *propertyNameList = NULL;
@@ -647,18 +646,13 @@ esxConnectToHost(esxPrivate *priv,
         }
     }
 
-    unescapedPassword = virAuthGetPassword(conn, auth, "esx", username, conn->uri->server);
+    password = virAuthGetPassword(conn, auth, "esx", username, conn->uri->server);
 
-    if (!unescapedPassword) {
+    if (!password) {
         virReportError(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
         goto cleanup;
     }
 
-    password = esxUtil_EscapeForXml(unescapedPassword);
-
-    if (!password)
-        goto cleanup;
-
     if (virAsprintf(&url, "%s://%s:%d/sdk", priv->parsedUri->transport,
                     conn->uri->server, conn->uri->port) < 0)
         goto cleanup;
@@ -705,7 +699,6 @@ esxConnectToHost(esxPrivate *priv,
 
  cleanup:
     VIR_FREE(username);
-    VIR_FREE(unescapedPassword);
     VIR_FREE(password);
     VIR_FREE(url);
     esxVI_String_Free(&propertyNameList);
@@ -726,7 +719,6 @@ esxConnectToVCenter(esxPrivate *priv,
     int result = -1;
     char ipAddress[NI_MAXHOST] = "";
     char *username = NULL;
-    char *unescapedPassword = NULL;
     char *password = NULL;
     char *url = NULL;
 
@@ -752,18 +744,13 @@ esxConnectToVCenter(esxPrivate *priv,
         }
     }
 
-    unescapedPassword = virAuthGetPassword(conn, auth, "esx", username, hostname);
+    password = virAuthGetPassword(conn, auth, "esx", username, hostname);
 
-    if (!unescapedPassword) {
+    if (!password) {
         virReportError(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
         goto cleanup;
     }
 
-    password = esxUtil_EscapeForXml(unescapedPassword);
-
-    if (!password)
-        goto cleanup;
-
     if (virAsprintf(&url, "%s://%s:%d/sdk", priv->parsedUri->transport,
                     hostname, conn->uri->port) < 0)
         goto cleanup;
@@ -799,7 +786,6 @@ esxConnectToVCenter(esxPrivate *priv,
 
  cleanup:
     VIR_FREE(username);
-    VIR_FREE(unescapedPassword);
     VIR_FREE(password);
     VIR_FREE(url);
 
index 652019644f0885a4274091986641618ff0840921..bbf3721b9b4f8bef7b2a70fc3560ace1e9bcb6cf 100644 (file)
@@ -996,39 +996,51 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
                       const char *ipAddress, const char *username,
                       const char *password, esxUtil_ParsedUri *parsedUri)
 {
+    int result = -1;
+    char *escapedPassword = NULL;
+
     if (!ctx || !url || !ipAddress || !username ||
         !password || ctx->url || ctx->service || ctx->curl) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
         return -1;
     }
 
+    escapedPassword = esxUtil_EscapeForXml(password);
+
+    if (!escapedPassword) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Failed to escape password for XML"));
+        goto cleanup;
+    }
+
     if (esxVI_CURL_Alloc(&ctx->curl) < 0 ||
         esxVI_CURL_Connect(ctx->curl, parsedUri) < 0 ||
         VIR_STRDUP(ctx->url, url) < 0 ||
         VIR_STRDUP(ctx->ipAddress, ipAddress) < 0 ||
         VIR_STRDUP(ctx->username, username) < 0 ||
         VIR_STRDUP(ctx->password, password) < 0) {
-        return -1;
+        goto cleanup;
     }
 
     if (VIR_ALLOC(ctx->sessionLock) < 0)
-        return -1;
+        goto cleanup;
+
 
     if (virMutexInit(ctx->sessionLock) < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Could not initialize session mutex"));
-        return -1;
+        goto cleanup;
     }
 
     if (esxVI_RetrieveServiceContent(ctx, &ctx->service) < 0)
-        return -1;
+        goto cleanup;
 
     if (STRNEQ(ctx->service->about->apiType, "HostAgent") &&
         STRNEQ(ctx->service->about->apiType, "VirtualCenter")) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Expecting VI API type 'HostAgent' or 'VirtualCenter' "
                          "but found '%s'"), ctx->service->about->apiType);
-        return -1;
+        goto cleanup;
     }
 
     if (virParseVersionString(ctx->service->about->apiVersion,
@@ -1036,14 +1048,14 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Could not parse VI API version '%s'"),
                        ctx->service->about->apiVersion);
-        return -1;
+        goto cleanup;
     }
 
     if (ctx->apiVersion < 1000000 * 2 + 1000 * 5 /* 2.5 */) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Minimum supported %s version is %s but found version '%s'"),
                        "VI API", "2.5", ctx->service->about->apiVersion);
-        return -1;
+        goto cleanup;
     }
 
     if (virParseVersionString(ctx->service->about->version,
@@ -1051,7 +1063,7 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Could not parse product version '%s'"),
                        ctx->service->about->version);
-        return -1;
+        goto cleanup;
     }
 
     if (STREQ(ctx->service->about->productLineId, "gsx")) {
@@ -1060,7 +1072,7 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
                            _("Minimum supported %s version is %s but found version '%s'"),
                            esxVI_ProductLineToDisplayName(esxVI_ProductLine_GSX),
                            "2.0", ctx->service->about->version);
-            return -1;
+            goto cleanup;
         }
 
         ctx->productLine = esxVI_ProductLine_GSX;
@@ -1071,7 +1083,7 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
                            _("Minimum supported %s version is %s but found version '%s'"),
                            esxVI_ProductLineToDisplayName(esxVI_ProductLine_ESX),
                            "3.5", ctx->service->about->version);
-            return -1;
+            goto cleanup;
         }
 
         ctx->productLine = esxVI_ProductLine_ESX;
@@ -1081,7 +1093,7 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
                            _("Minimum supported %s version is %s but found version '%s'"),
                            esxVI_ProductLineToDisplayName(esxVI_ProductLine_VPX),
                            "2.5", ctx->service->about->version);
-            return -1;
+            goto cleanup;
         }
 
         ctx->productLine = esxVI_ProductLine_VPX;
@@ -1090,7 +1102,7 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
                        _("Expecting product 'gsx' or 'esx' or 'embeddedEsx' "
                          "or 'vpx' but found '%s'"),
                        ctx->service->about->productLineId);
-        return -1;
+        goto cleanup;
     }
 
     if (ctx->productLine == esxVI_ProductLine_ESX) {
@@ -1107,12 +1119,19 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
     if (ctx->productLine == esxVI_ProductLine_VPX)
         ctx->hasSessionIsActive = true;
 
-    if (esxVI_Login(ctx, username, password, NULL, &ctx->session) < 0 ||
+
+
+    if (esxVI_Login(ctx, username, escapedPassword, NULL, &ctx->session) < 0 ||
         esxVI_BuildSelectSetCollection(ctx) < 0) {
-        return -1;
+        goto cleanup;
     }
 
-    return 0;
+    result = 0;
+
+ cleanup:
+    VIR_FREE(escapedPassword);
+
+    return result;
 }
 
 int
@@ -2062,6 +2081,7 @@ esxVI_EnsureSession(esxVI_Context *ctx)
     esxVI_ObjectContent *sessionManager = NULL;
     esxVI_DynamicProperty *dynamicProperty = NULL;
     esxVI_UserSession *currentSession = NULL;
+    char *escapedPassword = NULL;
 
     if (!ctx->sessionLock) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid call, no mutex"));
@@ -2075,6 +2095,14 @@ esxVI_EnsureSession(esxVI_Context *ctx)
         goto cleanup;
     }
 
+    escapedPassword = esxUtil_EscapeForXml(ctx->password);
+
+    if (!escapedPassword) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Failed to escape password for XML"));
+        goto cleanup;
+    }
+
     if (esxVI_String_AppendValueToList(&propertyNameList,
                                        "currentSession") < 0 ||
         esxVI_LookupObjectContentByType(ctx, ctx->service->sessionManager,
@@ -2101,7 +2129,7 @@ esxVI_EnsureSession(esxVI_Context *ctx)
     if (!currentSession) {
         esxVI_UserSession_Free(&ctx->session);
 
-        if (esxVI_Login(ctx, ctx->username, ctx->password, NULL,
+        if (esxVI_Login(ctx, ctx->username, escapedPassword, NULL,
                         &ctx->session) < 0) {
             goto cleanup;
         }
@@ -2117,6 +2145,7 @@ esxVI_EnsureSession(esxVI_Context *ctx)
  cleanup:
     virMutexUnlock(ctx->sessionLock);
 
+    VIR_FREE(escapedPassword);
     esxVI_String_Free(&propertyNameList);
     esxVI_ObjectContent_Free(&sessionManager);
     esxVI_UserSession_Free(&currentSession);