diff options
author | Ondrej Holy <oholy@redhat.com> | 2020-09-30 15:07:26 +0200 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2020-10-01 09:08:17 +0200 |
commit | 21329864ed78414c593a2c9e0b98f973e8171384 (patch) | |
tree | e0db84a0b1b742e975483d52af1ae1f9d246a9cc | |
parent | 34eb6f637203da43128e19c541b96a4f4c5e2e60 (diff) | |
download | gvfs-sftp-multiplexing-2fa.tar.gz |
sftp: Add support for two factor authenticationsftp-multiplexing-2fa
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
-rw-r--r-- | daemon/gvfsbackendsftp.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/daemon/gvfsbackendsftp.c b/daemon/gvfsbackendsftp.c index 1ecdd0d8..3951afb2 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) { |