mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Refactor code prompting for SASL credentials
SASL may prompt for credentials after either a 'start' or 'step' invocation. In both cases the code to handle this is the same. Refactor this code into a separate method to reduce the duplication, since the complexity is about to grow * src/remote/remote_driver.c: Refactor interaction with SASL Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
a4fb88b5c9
commit
c6c66615c2
@ -2863,7 +2863,8 @@ static sasl_callback_t *remoteAuthMakeCallbacks(int *credtype, int ncredtype)
|
|||||||
* are basically a 1-to-1 copy of each other.
|
* are basically a 1-to-1 copy of each other.
|
||||||
*/
|
*/
|
||||||
static int remoteAuthMakeCredentials(sasl_interact_t *interact,
|
static int remoteAuthMakeCredentials(sasl_interact_t *interact,
|
||||||
virConnectCredentialPtr *cred)
|
virConnectCredentialPtr *cred,
|
||||||
|
size_t *ncred)
|
||||||
{
|
{
|
||||||
int ninteract;
|
int ninteract;
|
||||||
if (!cred)
|
if (!cred)
|
||||||
@ -2889,16 +2890,8 @@ static int remoteAuthMakeCredentials(sasl_interact_t *interact,
|
|||||||
(*cred)[ninteract].result = NULL;
|
(*cred)[ninteract].result = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ninteract;
|
*ncred = ninteract;
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
static void remoteAuthFreeCredentials(virConnectCredentialPtr cred,
|
|
||||||
int ncred)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0 ; i < ncred ; i++)
|
|
||||||
VIR_FREE(cred[i].result);
|
|
||||||
VIR_FREE(cred);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2919,6 +2912,69 @@ static void remoteAuthFillInteract(virConnectCredentialPtr cred,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct remoteAuthInteractState {
|
||||||
|
sasl_interact_t *interact;
|
||||||
|
virConnectCredentialPtr cred;
|
||||||
|
size_t ncred;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void remoteAuthInteractStateClear(struct remoteAuthInteractState *state)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
if (!state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0 ; i < state->ncred ; i++)
|
||||||
|
VIR_FREE(state->cred[i].result);
|
||||||
|
VIR_FREE(state->cred);
|
||||||
|
state->ncred = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int remoteAuthInteract(struct remoteAuthInteractState *state,
|
||||||
|
virConnectAuthPtr auth)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
remoteAuthInteractStateClear(state);
|
||||||
|
|
||||||
|
if (remoteAuthMakeCredentials(state->interact, &state->cred, &state->ncred) < 0) {
|
||||||
|
remoteError(VIR_ERR_AUTH_FAILED, "%s",
|
||||||
|
_("Failed to make auth credentials"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run the authentication callback */
|
||||||
|
if (!auth || !auth->cb) {
|
||||||
|
remoteError(VIR_ERR_AUTH_FAILED, "%s",
|
||||||
|
_("No authentication callback available"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*(auth->cb))(state->cred, state->ncred, auth->cbdata) < 0) {
|
||||||
|
remoteError(VIR_ERR_AUTH_FAILED, "%s",
|
||||||
|
_("Failed to collect auth credentials"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteAuthFillInteract(state->cred, state->interact);
|
||||||
|
/*
|
||||||
|
* 'interact' now has pointers to strings in 'state->cred'
|
||||||
|
* so we must not free state->cred until the *next*
|
||||||
|
* sasl_start/step function is complete. Hence we
|
||||||
|
* call remoteAuthInteractStateClear() at the *start*
|
||||||
|
* of this method, rather than the end.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Perform the SASL authentication process
|
/* Perform the SASL authentication process
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
@ -2937,13 +2993,13 @@ remoteAuthSASL (virConnectPtr conn, struct private_data *priv,
|
|||||||
int err, complete;
|
int err, complete;
|
||||||
int ssf;
|
int ssf;
|
||||||
sasl_callback_t *saslcb = NULL;
|
sasl_callback_t *saslcb = NULL;
|
||||||
sasl_interact_t *interact = NULL;
|
|
||||||
virConnectCredentialPtr cred = NULL;
|
|
||||||
int ncred = 0;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
const char *mechlist;
|
const char *mechlist;
|
||||||
virNetSASLContextPtr saslCtxt;
|
virNetSASLContextPtr saslCtxt;
|
||||||
virNetSASLSessionPtr sasl = NULL;
|
virNetSASLSessionPtr sasl = NULL;
|
||||||
|
struct remoteAuthInteractState state;
|
||||||
|
|
||||||
|
memset(&state, 0, sizeof(state));
|
||||||
|
|
||||||
VIR_DEBUG("Client initialize SASL authentication");
|
VIR_DEBUG("Client initialize SASL authentication");
|
||||||
|
|
||||||
@ -3010,7 +3066,7 @@ remoteAuthSASL (virConnectPtr conn, struct private_data *priv,
|
|||||||
VIR_DEBUG("Client start negotiation mechlist '%s'", mechlist);
|
VIR_DEBUG("Client start negotiation mechlist '%s'", mechlist);
|
||||||
if ((err = virNetSASLSessionClientStart(sasl,
|
if ((err = virNetSASLSessionClientStart(sasl,
|
||||||
mechlist,
|
mechlist,
|
||||||
&interact,
|
&state.interact,
|
||||||
&clientout,
|
&clientout,
|
||||||
&clientoutlen,
|
&clientoutlen,
|
||||||
&mech)) < 0)
|
&mech)) < 0)
|
||||||
@ -3018,29 +3074,11 @@ remoteAuthSASL (virConnectPtr conn, struct private_data *priv,
|
|||||||
|
|
||||||
/* Need to gather some credentials from the client */
|
/* Need to gather some credentials from the client */
|
||||||
if (err == VIR_NET_SASL_INTERACT) {
|
if (err == VIR_NET_SASL_INTERACT) {
|
||||||
const char *msg;
|
if (remoteAuthInteract(&state, auth) < 0) {
|
||||||
if (cred) {
|
|
||||||
remoteAuthFreeCredentials(cred, ncred);
|
|
||||||
cred = NULL;
|
|
||||||
}
|
|
||||||
if ((ncred = remoteAuthMakeCredentials(interact, &cred)) < 0) {
|
|
||||||
remoteError(VIR_ERR_AUTH_FAILED, "%s",
|
|
||||||
_("Failed to make auth credentials"));
|
|
||||||
VIR_FREE(iret.mechlist);
|
VIR_FREE(iret.mechlist);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
/* Run the authentication callback */
|
goto restart;
|
||||||
if (auth && auth->cb) {
|
|
||||||
if ((*(auth->cb))(cred, ncred, auth->cbdata) >= 0) {
|
|
||||||
remoteAuthFillInteract(cred, interact);
|
|
||||||
goto restart;
|
|
||||||
}
|
|
||||||
msg = "Failed to collect auth credentials";
|
|
||||||
} else {
|
|
||||||
msg = "No authentication callback available";
|
|
||||||
}
|
|
||||||
remoteError(VIR_ERR_AUTH_FAILED, "%s", msg);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
VIR_FREE(iret.mechlist);
|
VIR_FREE(iret.mechlist);
|
||||||
|
|
||||||
@ -3081,35 +3119,18 @@ remoteAuthSASL (virConnectPtr conn, struct private_data *priv,
|
|||||||
if ((err = virNetSASLSessionClientStep(sasl,
|
if ((err = virNetSASLSessionClientStep(sasl,
|
||||||
serverin,
|
serverin,
|
||||||
serverinlen,
|
serverinlen,
|
||||||
&interact,
|
&state.interact,
|
||||||
&clientout,
|
&clientout,
|
||||||
&clientoutlen)) < 0)
|
&clientoutlen)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Need to gather some credentials from the client */
|
/* Need to gather some credentials from the client */
|
||||||
if (err == VIR_NET_SASL_INTERACT) {
|
if (err == VIR_NET_SASL_INTERACT) {
|
||||||
const char *msg;
|
if (remoteAuthInteract(&state, auth) < 0) {
|
||||||
if (cred) {
|
VIR_FREE(iret.mechlist);
|
||||||
remoteAuthFreeCredentials(cred, ncred);
|
|
||||||
cred = NULL;
|
|
||||||
}
|
|
||||||
if ((ncred = remoteAuthMakeCredentials(interact, &cred)) < 0) {
|
|
||||||
remoteError(VIR_ERR_AUTH_FAILED, "%s",
|
|
||||||
_("Failed to make auth credentials"));
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
/* Run the authentication callback */
|
goto restep;
|
||||||
if (auth && auth->cb) {
|
|
||||||
if ((*(auth->cb))(cred, ncred, auth->cbdata) >= 0) {
|
|
||||||
remoteAuthFillInteract(cred, interact);
|
|
||||||
goto restep;
|
|
||||||
}
|
|
||||||
msg = _("Failed to collect auth credentials");
|
|
||||||
} else {
|
|
||||||
msg = _("No authentication callback available");
|
|
||||||
}
|
|
||||||
remoteError(VIR_ERR_AUTH_FAILED, "%s", msg);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_FREE(serverin);
|
VIR_FREE(serverin);
|
||||||
@ -3171,8 +3192,8 @@ remoteAuthSASL (virConnectPtr conn, struct private_data *priv,
|
|||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(serverin);
|
VIR_FREE(serverin);
|
||||||
|
|
||||||
|
remoteAuthInteractStateClear(&state);
|
||||||
VIR_FREE(saslcb);
|
VIR_FREE(saslcb);
|
||||||
remoteAuthFreeCredentials(cred, ncred);
|
|
||||||
virNetSASLSessionFree(sasl);
|
virNetSASLSessionFree(sasl);
|
||||||
virNetSASLContextFree(saslCtxt);
|
virNetSASLContextFree(saslCtxt);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user