From 59528741810720424fe7ea290df6e8d538533039 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Wed, 30 Sep 2020 15:07:26 +0200 Subject: sftp: Add support for two factor authentication Currently, SFTP backend timeouts when two factor authentication is used as it doesn't expect another prompt. Let's handle "Verification code" and "One-time password" prompts and ask user to enter the code. Fixes: https://gitlab.gnome.org/GNOME/gvfs/-/issues/480 --- daemon/gvfsbackendsftp.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/daemon/gvfsbackendsftp.c b/daemon/gvfsbackendsftp.c index 4ec4c58b..b86b7ebb 100644 --- a/daemon/gvfsbackendsftp.c +++ b/daemon/gvfsbackendsftp.c @@ -1265,6 +1265,55 @@ handle_login (GVfsBackend *backend, break; } } + else if (g_str_has_prefix (buffer, "Verification code") || + g_str_has_prefix (buffer, "One-time password")) + { + gchar *verification_code = NULL; + gboolean aborted = FALSE; + + g_debug ("handle_login #%d - asking for verification code...\n", i); + + if (op_backend->user_specified) + /* Translators: the first %s is the username, the second the host name */ + prompt = g_strdup_printf (_("Enter verification code for %s on %s"), + op_backend->user, op_backend->host); + else + /* Translators: %s is the hostname */ + prompt = g_strdup_printf (_("Enter verification code for %s"), + op_backend->host); + + if (!g_mount_source_ask_password (mount_source, prompt, + op_backend->user, NULL, + G_ASK_PASSWORD_NEED_PASSWORD, + &aborted, &verification_code, + NULL, NULL, NULL, NULL) || + aborted) + { + g_set_error_literal (error, G_IO_ERROR, aborted ? + G_IO_ERROR_FAILED_HANDLED : + G_IO_ERROR_PERMISSION_DENIED, + _("Password dialog cancelled")); + ret_val = FALSE; + break; + } + g_free (prompt); + + if (!g_output_stream_write_all (reply_stream, verification_code, + strlen (verification_code), NULL, + NULL, NULL) || + !g_output_stream_write_all (reply_stream, "\n", 1, NULL, NULL, + NULL)) + { + g_free (verification_code); + g_set_error_literal (error, + G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, + _("Can’t send password")); + ret_val = FALSE; + break; + } + + g_free (verification_code); + } else if (g_str_has_prefix (buffer, "The authenticity of host '") || strstr (buffer, "Key fingerprint:") != NULL) { -- cgit v1.2.1