diff options
author | Ondrej Holy <oholy@redhat.com> | 2020-09-30 15:07:26 +0200 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2020-11-30 09:25:26 +0000 |
commit | 59528741810720424fe7ea290df6e8d538533039 (patch) | |
tree | 6a4240cebe7503e43f4899cac18e508e05caebe1 | |
parent | cf540d8dd52ff024cb387a253da8169ef3e54717 (diff) | |
download | gvfs-59528741810720424fe7ea290df6e8d538533039.tar.gz |
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
-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 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) { |