[gvfs/sftp-multiplexing-2fa: 2/2] sftp: Add support for two factor authentication




commit 8c7f9c3e3c4f3cdf810d0884fd7199572d5573f6
Author: Ondrej Holy <oholy redhat com>
Date:   Wed Sep 30 15:07:26 2020 +0200

    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 4f0d5ac4..6eda004b 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)
         {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]