commit 7910ef3ee50a847edf72d755381699f169d46278 Author: Adam Majer Date: Mon Jun 25 15:06:38 2018 +0200 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 diff --git a/src/vfs/sftpfs/connection.c b/src/vfs/sftpfs/connection.c index 537159129..a6b7d1b2c 100644 --- a/src/vfs/sftpfs/connection.c +++ b/src/vfs/sftpfs/connection.c @@ -292,6 +292,53 @@ 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 const char *kbi_passwd; +static const struct vfs_s_super *kbi_super; +static +LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC (keyboard_interactive_helper) +{ + int i; + int len; + + (void) instruction; + (void) instruction_len; + (void) abstract; + + if (!kbi_super || !kbi_passwd) + 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. @@ -323,6 +370,18 @@ 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, + 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); @@ -337,6 +396,19 @@ 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, + keyboard_interactive_helper)) == + LIBSSH2_ERROR_EAGAIN); + kbi_super = NULL; + kbi_passwd = NULL; + } + if (rc == 0) { ret_value = TRUE;