static int
-esxConnectToHost(esxPrivate *priv, virConnectAuthPtr auth,
- const char *hostname, int port,
- const char *predefinedUsername,
- esxVI_ProductVersion expectedProductVersion,
+esxConnectToHost(virConnectPtr conn,
+ virConnectAuthPtr auth,
char **vCenterIpAddress)
{
int result = -1;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *hostSystem = NULL;
esxVI_Boolean inMaintenanceMode = esxVI_Boolean_Undefined;
+ esxPrivate *priv = conn->privateData;
+ esxVI_ProductVersion expectedProductVersion = STRCASEEQ(conn->uri->scheme, "esx")
+ ? esxVI_ProductVersion_ESX
+ : esxVI_ProductVersion_GSX;
if (vCenterIpAddress == NULL || *vCenterIpAddress != NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
return -1;
}
- if (esxUtil_ResolveHostname(hostname, ipAddress, NI_MAXHOST) < 0) {
+ if (esxUtil_ResolveHostname(conn->uri->server, ipAddress, NI_MAXHOST) < 0) {
return -1;
}
- if (predefinedUsername != NULL) {
- username = strdup(predefinedUsername);
+ if (conn->uri->user != NULL) {
+ username = strdup(conn->uri->user);
if (username == NULL) {
virReportOOMError();
goto cleanup;
}
} else {
- username = virAuthGetUsername(auth, "root", hostname);
+ username = virAuthGetUsername(conn, auth, "esx", "root", conn->uri->server);
if (username == NULL) {
ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed"));
}
}
- unescapedPassword = virAuthGetPassword(auth, username, hostname);
+ unescapedPassword = virAuthGetPassword(conn, auth, "esx", username, conn->uri->server);
if (unescapedPassword == NULL) {
ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
}
if (virAsprintf(&url, "%s://%s:%d/sdk", priv->parsedUri->transport,
- hostname, port) < 0) {
+ conn->uri->server, conn->uri->port) < 0) {
virReportOOMError();
goto cleanup;
}
priv->host->productVersion != esxVI_ProductVersion_ESX5x) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("%s is neither an ESX 3.5, 4.x nor 5.x host"),
- hostname);
+ conn->uri->server);
goto cleanup;
}
} else { /* GSX */
if (priv->host->productVersion != esxVI_ProductVersion_GSX20) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("%s isn't a GSX 2.0 host"), hostname);
+ _("%s isn't a GSX 2.0 host"), conn->uri->server);
goto cleanup;
}
}
static int
-esxConnectToVCenter(esxPrivate *priv, virConnectAuthPtr auth,
- const char *hostname, int port,
- const char *predefinedUsername,
+esxConnectToVCenter(virConnectPtr conn,
+ virConnectAuthPtr auth,
+ const char *hostname,
const char *hostSystemIpAddress)
{
int result = -1;
char *unescapedPassword = NULL;
char *password = NULL;
char *url = NULL;
+ esxPrivate *priv = conn->privateData;
if (hostSystemIpAddress == NULL &&
(priv->parsedUri->path == NULL || STREQ(priv->parsedUri->path, "/"))) {
return -1;
}
- if (predefinedUsername != NULL) {
- username = strdup(predefinedUsername);
+ if (conn->uri->user != NULL) {
+ username = strdup(conn->uri->user);
if (username == NULL) {
virReportOOMError();
goto cleanup;
}
} else {
- username = virAuthGetUsername(auth, "administrator", hostname);
+ username = virAuthGetUsername(conn, auth, "esx", "administrator", hostname);
if (username == NULL) {
ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed"));
}
}
- unescapedPassword = virAuthGetPassword(auth, username, hostname);
+ unescapedPassword = virAuthGetPassword(conn, auth, "esx", username, hostname);
if (unescapedPassword == NULL) {
ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
}
if (virAsprintf(&url, "%s://%s:%d/sdk", priv->parsedUri->transport,
- hostname, port) < 0) {
+ hostname, conn->uri->port) < 0) {
virReportOOMError();
goto cleanup;
}
if (STRCASEEQ(conn->uri->scheme, "esx") ||
STRCASEEQ(conn->uri->scheme, "gsx")) {
/* Connect to host */
- if (esxConnectToHost(priv, auth, conn->uri->server, conn->uri->port,
- conn->uri->user,
- STRCASEEQ(conn->uri->scheme, "esx")
- ? esxVI_ProductVersion_ESX
- : esxVI_ProductVersion_GSX,
+ if (esxConnectToHost(conn, auth,
&potentialVCenterIpAddress) < 0) {
goto cleanup;
}
}
}
- if (esxConnectToVCenter(priv, auth, vCenterIpAddress,
- conn->uri->port, NULL,
+ if (esxConnectToVCenter(conn, auth,
+ vCenterIpAddress,
priv->host->ipAddress) < 0) {
goto cleanup;
}
priv->primary = priv->host;
} else { /* VPX */
/* Connect to vCenter */
- if (esxConnectToVCenter(priv, auth, conn->uri->server, conn->uri->port,
- conn->uri->user, NULL) < 0) {
+ if (esxConnectToVCenter(conn, auth,
+ conn->uri->server,
+ NULL) < 0) {
goto cleanup;
}
goto cleanup;
}
} else {
- username = virAuthGetUsername(auth, "administrator", conn->uri->server);
+ username = virAuthGetUsername(conn, auth, "hyperv", "administrator", conn->uri->server);
if (username == NULL) {
HYPERV_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed"));
}
}
- password = virAuthGetPassword(auth, username, conn->uri->server);
+ password = virAuthGetPassword(conn, auth, "hyperv", username, conn->uri->server);
if (password == NULL) {
HYPERV_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
goto err;
}
- username = virAuthGetUsername(auth, NULL, conn->uri->server);
+ username = virAuthGetUsername(conn, auth, "ssh", NULL, conn->uri->server);
if (username == NULL) {
PHYP_ERROR(VIR_ERR_AUTH_FAILED, "%s",
goto disconnect;
}
- password = virAuthGetPassword(auth, username, conn->uri->server);
+ password = virAuthGetPassword(conn, auth, "ssh", username, conn->uri->server);
if (password == NULL) {
PHYP_ERROR(VIR_ERR_AUTH_FAILED, "%s",
#include "intprops.h"
#include "virtypedparam.h"
#include "viruri.h"
+#include "virauth.h"
+#include "virauthconfig.h"
#define VIR_FROM_THIS VIR_FROM_REMOTE
pkipath = strdup(var->value);
if (!pkipath) goto out_of_memory;
var->ignore = 1;
+ } else if (STRCASEEQ(var->name, "authfile")) {
+ /* Strip this param, used by virauth.c */
+ var->ignore = 1;
} else {
VIR_DEBUG("passing through variable '%s' ('%s') to remote end",
var->name, var->value);
if (!cred)
return -1;
- for (ninteract = 0 ; interact[ninteract].id != 0 ; ninteract++)
- ; /* empty */
+ for (ninteract = 0, *ncred = 0 ; interact[ninteract].id != 0 ; ninteract++) {
+ if (interact[ninteract].result)
+ continue;
+ (*ncred)++;
+ }
- if (VIR_ALLOC_N(*cred, ninteract) < 0)
+ if (VIR_ALLOC_N(*cred, *ncred) < 0)
return -1;
- for (ninteract = 0 ; interact[ninteract].id != 0 ; ninteract++) {
- (*cred)[ninteract].type = remoteAuthCredSASL2Vir(interact[ninteract].id);
- if (!(*cred)[ninteract].type) {
+ for (ninteract = 0, *ncred = 0 ; interact[ninteract].id != 0 ; ninteract++) {
+ if (interact[ninteract].result)
+ continue;
+
+ (*cred)[*ncred].type = remoteAuthCredSASL2Vir(interact[ninteract].id);
+ if (!(*cred)[*ncred].type) {
+ *ncred = 0;
VIR_FREE(*cred);
return -1;
}
- if (interact[ninteract].challenge)
- (*cred)[ninteract].challenge = interact[ninteract].challenge;
- (*cred)[ninteract].prompt = interact[ninteract].prompt;
- if (interact[ninteract].defresult)
- (*cred)[ninteract].defresult = interact[ninteract].defresult;
- (*cred)[ninteract].result = NULL;
+ if (interact[*ncred].challenge)
+ (*cred)[*ncred].challenge = interact[ninteract].challenge;
+ (*cred)[*ncred].prompt = interact[ninteract].prompt;
+ if (interact[*ncred].defresult)
+ (*cred)[*ncred].defresult = interact[ninteract].defresult;
+ (*cred)[*ncred].result = NULL;
+
+ (*ncred)++;
}
- *ncred = ninteract;
return 0;
}
static void remoteAuthFillInteract(virConnectCredentialPtr cred,
sasl_interact_t *interact)
{
- int ninteract;
- for (ninteract = 0 ; interact[ninteract].id != 0 ; ninteract++) {
- interact[ninteract].result = cred[ninteract].result;
- interact[ninteract].len = cred[ninteract].resultlen;
+ int ninteract, ncred;
+ for (ninteract = 0, ncred = 0 ; interact[ninteract].id != 0 ; ninteract++) {
+ if (interact[ninteract].result)
+ continue;
+ interact[ninteract].result = cred[ncred].result;
+ interact[ninteract].len = cred[ncred].resultlen;
+ ncred++;
}
}
-
struct remoteAuthInteractState {
sasl_interact_t *interact;
virConnectCredentialPtr cred;
size_t ncred;
+ virAuthConfigPtr config;
};
-static void remoteAuthInteractStateClear(struct remoteAuthInteractState *state)
+
+static int remoteAuthFillFromConfig(virConnectPtr conn,
+ struct remoteAuthInteractState *state)
+{
+ int ret = -1;
+ int ninteract;
+ const char *credname;
+ char *path = NULL;
+
+ VIR_DEBUG("Trying to fill auth parameters from config file");
+
+ if (!state->config) {
+ if (virAuthGetConfigFilePath(conn, &path) < 0)
+ goto cleanup;
+ if (path == NULL) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (!(state->config = virAuthConfigNew(path)))
+ goto cleanup;
+ }
+
+ for (ninteract = 0 ; state->interact[ninteract].id != 0 ; ninteract++) {
+ const char *value = NULL;
+
+ switch (state->interact[ninteract].id) {
+ case SASL_CB_USER:
+ credname = "username";
+ break;
+ case SASL_CB_AUTHNAME:
+ credname = "authname";
+ break;
+ case SASL_CB_PASS:
+ credname = "password";
+ break;
+ case SASL_CB_GETREALM:
+ credname = "realm";
+ break;
+ default:
+ credname = NULL;
+ break;
+ }
+
+ if (virAuthConfigLookup(state->config,
+ "libvirt",
+ conn->uri->server,
+ credname,
+ &value) < 0)
+ goto cleanup;
+
+ if (value) {
+ state->interact[ninteract].result = value;
+ state->interact[ninteract].len = strlen(value);
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(path);
+ return ret;
+}
+
+
+static void remoteAuthInteractStateClear(struct remoteAuthInteractState *state,
+ bool final)
{
size_t i;
if (!state)
VIR_FREE(state->cred[i].result);
VIR_FREE(state->cred);
state->ncred = 0;
+
+ if (final)
+ virAuthConfigFree(state->config);
}
-static int remoteAuthInteract(struct remoteAuthInteractState *state,
+static int remoteAuthInteract(virConnectPtr conn,
+ struct remoteAuthInteractState *state,
virConnectAuthPtr auth)
{
int ret = -1;
- remoteAuthInteractStateClear(state);
+ VIR_DEBUG("Starting SASL interaction");
+ remoteAuthInteractStateClear(state, false);
+
+ if (remoteAuthFillFromConfig(conn, state) < 0)
+ goto cleanup;
if (remoteAuthMakeCredentials(state->interact, &state->cred, &state->ncred) < 0) {
remoteError(VIR_ERR_AUTH_FAILED, "%s",
/* Need to gather some credentials from the client */
if (err == VIR_NET_SASL_INTERACT) {
- if (remoteAuthInteract(&state, auth) < 0) {
+ if (remoteAuthInteract(conn, &state, auth) < 0) {
VIR_FREE(iret.mechlist);
goto cleanup;
}
/* Need to gather some credentials from the client */
if (err == VIR_NET_SASL_INTERACT) {
- if (remoteAuthInteract(&state, auth) < 0) {
+ if (remoteAuthInteract(conn, &state, auth) < 0) {
VIR_FREE(iret.mechlist);
goto cleanup;
}
cleanup:
VIR_FREE(serverin);
- remoteAuthInteractStateClear(&state);
+ remoteAuthInteractStateClear(&state, true);
VIR_FREE(saslcb);
virNetSASLSessionFree(sasl);
virNetSASLContextFree(saslCtxt);
#include "datatypes.h"
#include "virterror_internal.h"
#include "configmake.h"
+#include "virauthconfig.h"
#define VIR_FROM_THIS VIR_FROM_AUTH
}
+static int
+virAuthGetCredential(virConnectPtr conn,
+ const char *servicename,
+ const char *credname,
+ char **value)
+{
+ int ret = -1;
+ char *path = NULL;
+ virAuthConfigPtr config = NULL;
+ const char *tmp;
+
+ *value = NULL;
+
+ if (virAuthGetConfigFilePath(conn, &path) < 0)
+ goto cleanup;
+
+ if (path == NULL) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (!(config = virAuthConfigNew(path)))
+ goto cleanup;
+
+ if (virAuthConfigLookup(config,
+ servicename,
+ conn->uri->server,
+ credname,
+ &tmp) < 0)
+ goto cleanup;
+
+ if (tmp &&
+ !(*value = strdup(tmp))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ virAuthConfigFree(config);
+ VIR_FREE(path);
+ return ret;
+}
+
+
char *
-virAuthGetUsername(virConnectAuthPtr auth, const char *defaultUsername,
+virAuthGetUsername(virConnectPtr conn,
+ virConnectAuthPtr auth,
+ const char *servicename,
+ const char *defaultUsername,
const char *hostname)
{
unsigned int ncred;
virConnectCredential cred;
char *prompt;
+ char *ret = NULL;
+
+ if (virAuthGetCredential(conn, servicename, "username", &ret) < 0)
+ return NULL;
+ if (ret != NULL)
+ return ret;
memset(&cred, 0, sizeof (virConnectCredential));
char *
-virAuthGetPassword(virConnectAuthPtr auth, const char *username,
+virAuthGetPassword(virConnectPtr conn,
+ virConnectAuthPtr auth,
+ const char *servicename,
+ const char *username,
const char *hostname)
{
unsigned int ncred;
virConnectCredential cred;
char *prompt;
+ char *ret = NULL;
+
+ if (virAuthGetCredential(conn, servicename, "password", &ret) < 0)
+ return NULL;
+ if (ret != NULL)
+ return ret;
memset(&cred, 0, sizeof (virConnectCredential));
int virAuthGetConfigFilePath(virConnectPtr conn,
char **path);
-char *virAuthGetUsername(virConnectAuthPtr auth, const char *defaultUsername,
+char *virAuthGetUsername(virConnectPtr conn,
+ virConnectAuthPtr auth,
+ const char *servicename,
+ const char *defaultUsername,
const char *hostname);
-char *virAuthGetPassword(virConnectAuthPtr auth, const char *username,
+char *virAuthGetPassword(virConnectPtr conn,
+ virConnectAuthPtr auth,
+ const char *servicename,
+ const char *username,
const char *hostname);
#endif /* __VIR_AUTH_H__ */
goto error;
}
} else {
- username = virAuthGetUsername(auth, NULL, conn->uri->server);
+ username = virAuthGetUsername(conn, auth, "xen", NULL, conn->uri->server);
if (username == NULL) {
xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED,
}
}
- password = virAuthGetPassword(auth, username, conn->uri->server);
+ password = virAuthGetPassword(conn, auth, "xen", username, conn->uri->server);
if (password == NULL) {
xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED,