summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Holy <oholy@redhat.com>2020-09-30 15:07:26 +0200
committerOndrej Holy <oholy@redhat.com>2020-11-30 09:25:26 +0000
commit59528741810720424fe7ea290df6e8d538533039 (patch)
tree6a4240cebe7503e43f4899cac18e508e05caebe1
parentcf540d8dd52ff024cb387a253da8169ef3e54717 (diff)
downloadgvfs-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.c49
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)
{