When keyboard-interactive authentication is disabled on a host libvirt fails when attempting authentication with password. This patch adds code that simulates keyboard interactive authentication using "password" auth method in libssh2. --- src/rpc/virnetsshsession.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/rpc/virnetsshsession.c b/src/rpc/virnetsshsession.c index 13a0368..9b35b03 100644 --- a/src/rpc/virnetsshsession.c +++ b/src/rpc/virnetsshsession.c @@ -34,6 +34,7 @@ #include "util.h" #include "virterror_internal.h" #include "virobject.h" +#include "virauth.h" #define VIR_FROM_THIS VIR_FROM_SSH @@ -769,6 +770,66 @@ virNetSSHAuthenticateKeyboardInteractive(virNetSSHSessionPtr sess, return 1; } +/* perform keyboard interactive authentication using fallback password method + * + * Returns: 0 on success + * 1 on authentication failure + * -1 on error + */ +static int +virNetSSHAuthenticateKeyboardFallback(virNetSSHSessionPtr sess, + virNetSSHAuthMethodPtr priv) +{ + char *password = NULL; + char *errmsg; + int ret = -1; + int rc; + + + if (!sess->cred || !sess->cred->cb) { + virReportError(VIR_ERR_SSH, "%s", + _("Can't perform authentication: " + "Authentication callback not provided")); + return -1; + } + + /* Try the authenticating the set amount of times. The server breaks the + * connection if maximum number of bad auth tries is exceeded */ + while (priv->tries < 0 || priv->tries-- > 0) { + if (!(password = virAuthGetPassword(NULL, sess->cred, NULL, + 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; + } + + /* error path */ + libssh2_session_last_error(sess->session, &errmsg, NULL, 0); + virReportError(VIR_ERR_AUTH_FAILED, + _("authentication failed: %s"), + errmsg); + + if (ret != LIBSSH2_ERROR_AUTHENTICATION_FAILED) + goto cleanup; + } + + /* authentication failed */ + ret = 1; + +cleanup: + VIR_FREE(password); + return ret; +} + + /* select auth method and authenticate */ static int virNetSSHAuthenticate(virNetSSHSessionPtr sess) @@ -814,6 +875,9 @@ virNetSSHAuthenticate(virNetSSHSessionPtr sess) case VIR_NET_SSH_AUTH_KEYBOARD_INTERACTIVE: if (strstr(auth_list, "keyboard-interactive")) ret = virNetSSHAuthenticateKeyboardInteractive(sess, auth); + else if (strstr(auth_list, "password")) + ret = virNetSSHAuthenticateKeyboardFallback(sess, auth); + break; case VIR_NET_SSH_AUTH_AGENT: if (strstr(auth_list, "publickey")) -- 1.8.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list