From dc830db8393c21aa243bad525043a5d9085d94f8 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Mon, 25 Jun 2018 15:06:38 +0200 Subject: [PATCH] Ticket #3921: enable keyboard interactive authentication. If SSH server does not support cleartext tunneled password authentication and only 'keyboard interactive' authentication instead, then we need to use different authentication function along with a interactive callback. Signed-off-by: Adam Majer Signed-off-by: Andrew Borodin --- src/vfs/sftpfs/connection.c | 81 +++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/vfs/sftpfs/connection.c b/src/vfs/sftpfs/connection.c index 16d4b9840..c42640136 100644 --- a/src/vfs/sftpfs/connection.c +++ b/src/vfs/sftpfs/connection.c @@ -53,6 +53,10 @@ /*** file scope variables ************************************************************************/ +static const char *kbi_passwd = NULL; +static const struct vfs_s_super *kbi_super = NULL; + +/* --------------------------------------------------------------------------------------------- */ /*** file scope functions ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ /** @@ -292,6 +296,51 @@ sftpfs_open_connection_ssh_key (struct vfs_s_super *super, GError ** mcerror) return ret_value; } +/* --------------------------------------------------------------------------------------------- */ + +/** + * Keyboard-interactive password helper for opening connection to host by + * sftpfs_open_connection_ssh_password + * + * Uses global kbi_super (data with existing connection) and kbi_passwd (password) + * + * @param name username + * @param name_len length of @name + * @param instruction unused + * @param instruction_len unused + * @param num_prompts number of possible problems to process + * @param prompts array of prompts to process + * @param responses array of responses, one per prompt + * @param abstract unused + */ + +static +LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC (sftpfs_keyboard_interactive_helper) +{ + int i; + size_t len; + + (void) instruction; + (void) instruction_len; + (void) abstract; + + if (kbi_super == NULL || kbi_passwd == NULL) + return; + + if (strncmp (name, kbi_super->path_element->user, name_len) != 0) + return; + + /* assume these are password prompts */ + len = strlen (kbi_passwd); + + for (i = 0; i < num_prompts; ++i) + if (strncmp (prompts[i].text, "Password: ", prompts[i].length) == 0) + { + responses[i].text = strdup (kbi_passwd); + responses[i].length = len; + } +} + /* --------------------------------------------------------------------------------------------- */ /** * Open connection to host using password. @@ -321,6 +370,22 @@ sftpfs_open_connection_ssh_password (struct vfs_s_super *super, GError ** mcerro LIBSSH2_ERROR_EAGAIN); if (rc == 0) return TRUE; + + kbi_super = super; + kbi_passwd = super->path_element->password; + + while ((rc = + libssh2_userauth_keyboard_interactive (sftpfs_super->session, + super->path_element->user, + sftpfs_keyboard_interactive_helper)) == + LIBSSH2_ERROR_EAGAIN) + ; + + kbi_super = NULL; + kbi_passwd = NULL; + + if (rc == 0) + return TRUE; } p = g_strdup_printf (_("sftp: Enter password for %s "), super->path_element->user); @@ -335,6 +400,22 @@ sftpfs_open_connection_ssh_password (struct vfs_s_super *super, GError ** mcerro passwd)) == LIBSSH2_ERROR_EAGAIN) ; + if (rc != 0) + { + kbi_super = super; + kbi_passwd = passwd; + + while ((rc = + libssh2_userauth_keyboard_interactive (sftpfs_super->session, + super->path_element->user, + sftpfs_keyboard_interactive_helper)) == + LIBSSH2_ERROR_EAGAIN) + ; + + kbi_super = NULL; + kbi_passwd = NULL; + } + if (rc == 0) { ret_value = TRUE;