mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
libssh2: Improve password based authentication
The password authentication method wasn't used as there wasn't a pleasant way to pass the password. This patch adds the option to use virAuth util functions to request the password either from a config file or uses the conf callback to request it from the user.
This commit is contained in:
parent
c7dba5d695
commit
676504e3be
@ -36,6 +36,7 @@
|
|||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
#include "virobject.h"
|
#include "virobject.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
|
#include "virauth.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_SSH
|
#define VIR_FROM_THIS VIR_FROM_SSH
|
||||||
|
|
||||||
@ -97,6 +98,7 @@ struct _virNetSSHSession {
|
|||||||
|
|
||||||
/* authentication stuff */
|
/* authentication stuff */
|
||||||
virConnectAuthPtr cred;
|
virConnectAuthPtr cred;
|
||||||
|
char *authPath;
|
||||||
virNetSSHAuthCallbackError authCbErr;
|
virNetSSHAuthCallbackError authCbErr;
|
||||||
size_t nauths;
|
size_t nauths;
|
||||||
virNetSSHAuthMethodPtr *auths;
|
virNetSSHAuthMethodPtr *auths;
|
||||||
@ -156,6 +158,7 @@ virNetSSHSessionDispose(void *obj)
|
|||||||
VIR_FREE(sess->channelCommand);
|
VIR_FREE(sess->channelCommand);
|
||||||
VIR_FREE(sess->hostname);
|
VIR_FREE(sess->hostname);
|
||||||
VIR_FREE(sess->knownHostsFile);
|
VIR_FREE(sess->knownHostsFile);
|
||||||
|
VIR_FREE(sess->authPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static virClassPtr virNetSSHSessionClass;
|
static virClassPtr virNetSSHSessionClass;
|
||||||
@ -672,7 +675,8 @@ virNetSSHAuthenticatePrivkey(virNetSSHSessionPtr sess,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* perform tunelled password authentication
|
|
||||||
|
/* perform password authentication, either directly or request the password
|
||||||
*
|
*
|
||||||
* Returns: 0 on success
|
* Returns: 0 on success
|
||||||
* 1 on authentication failure
|
* 1 on authentication failure
|
||||||
@ -682,27 +686,71 @@ static int
|
|||||||
virNetSSHAuthenticatePassword(virNetSSHSessionPtr sess,
|
virNetSSHAuthenticatePassword(virNetSSHSessionPtr sess,
|
||||||
virNetSSHAuthMethodPtr priv)
|
virNetSSHAuthMethodPtr priv)
|
||||||
{
|
{
|
||||||
|
char *password = NULL;
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
int ret;
|
int ret = -1;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* tunelled password authentication */
|
if (priv->password) {
|
||||||
if ((ret = libssh2_userauth_password(sess->session,
|
/* tunelled password authentication */
|
||||||
priv->username,
|
if ((ret = libssh2_userauth_password(sess->session,
|
||||||
priv->password)) < 0) {
|
priv->username,
|
||||||
libssh2_session_last_error(sess->session, &errmsg, NULL, 0);
|
priv->password)) == 0) {
|
||||||
virReportError(VIR_ERR_AUTH_FAILED,
|
ret = 0;
|
||||||
_("tunelled password authentication failed: %s"),
|
goto cleanup;
|
||||||
errmsg);
|
}
|
||||||
|
} else {
|
||||||
|
/* password authentication with interactive password request */
|
||||||
|
if (!sess->cred || !sess->cred->cb) {
|
||||||
|
virReportError(VIR_ERR_SSH, "%s",
|
||||||
|
_("Can't perform authentication: "
|
||||||
|
"Authentication callback not provided"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == LIBSSH2_ERROR_AUTHENTICATION_FAILED)
|
/* Try the authenticating the set amount of times. The server breaks the
|
||||||
return 1;
|
* connection if maximum number of bad auth tries is exceeded */
|
||||||
else
|
while (true) {
|
||||||
return -1;
|
if (!(password = virAuthGetPasswordPath(sess->authPath, sess->cred,
|
||||||
|
"ssh", priv->username,
|
||||||
|
sess->hostname))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("failed to retrieve password"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tunelled password authentication */
|
||||||
|
if ((rc = libssh2_userauth_password(sess->session,
|
||||||
|
priv->username,
|
||||||
|
password)) == 0) {
|
||||||
|
ret = 0;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != LIBSSH2_ERROR_AUTHENTICATION_FAILED)
|
||||||
|
break;
|
||||||
|
|
||||||
|
VIR_FREE(password);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* auth success */
|
|
||||||
return 0;
|
/* error path */
|
||||||
|
libssh2_session_last_error(sess->session, &errmsg, NULL, 0);
|
||||||
|
virReportError(VIR_ERR_AUTH_FAILED,
|
||||||
|
_("authentication failed: %s"), errmsg);
|
||||||
|
|
||||||
|
/* determine exist status */
|
||||||
|
if (ret == LIBSSH2_ERROR_AUTHENTICATION_FAILED)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(password);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* perform keyboard interactive authentication
|
/* perform keyboard interactive authentication
|
||||||
*
|
*
|
||||||
* Returns: 0 on success
|
* Returns: 0 on success
|
||||||
|
Loading…
x
Reference in New Issue
Block a user