Blame SOURCES/vinagre-3.14.3-store-credentials-for-rdp.patch

22448f
From 6c52168b3b3f1fddf6b21c01f69e2fb8bdd7ecd5 Mon Sep 17 00:00:00 2001
22448f
From: Marek Kasik <mkasik@redhat.com>
22448f
Date: Tue, 15 Sep 2015 16:38:09 +0200
22448f
Subject: [PATCH] Store credentials for RDP
22448f
22448f
Store credentials using secrets service if requested.
22448f
Handle unsuccessful authentications by asking user for credentials.
22448f
22448f
https://bugzilla.gnome.org/show_bug.cgi?id=753355
22448f
---
22448f
 plugins/rdp/vinagre-rdp-connection.c |  21 +++-
22448f
 plugins/rdp/vinagre-rdp-plugin.c     |  29 ++++-
22448f
 plugins/rdp/vinagre-rdp-tab.c        | 231 ++++++++++++++++++-----------------
22448f
 3 files changed, 159 insertions(+), 122 deletions(-)
22448f
22448f
diff --git a/plugins/rdp/vinagre-rdp-connection.c b/plugins/rdp/vinagre-rdp-connection.c
22448f
index 99182c7..66cf01f 100644
22448f
--- a/plugins/rdp/vinagre-rdp-connection.c
22448f
+++ b/plugins/rdp/vinagre-rdp-connection.c
22448f
@@ -58,8 +58,25 @@ rdp_parse_item (VinagreConnection *conn, xmlNode *root)
22448f
 static void
22448f
 rdp_parse_options_widget (VinagreConnection *conn, GtkWidget *widget)
22448f
 {
22448f
-  GtkWidget *u_entry, *spin_button;
22448f
-  guint      width, height;
22448f
+  const gchar *text;
22448f
+  GtkWidget   *u_entry, *d_entry, *spin_button, *scaling_button;
22448f
+  gboolean     scaling;
22448f
+  guint        width, height;
22448f
+
22448f
+  d_entry = g_object_get_data (G_OBJECT (widget), "domain_entry");
22448f
+  if (!d_entry)
22448f
+    {
22448f
+      g_warning ("Wrong widget passed to rdp_parse_options_widget()");
22448f
+      return;
22448f
+    }
22448f
+
22448f
+  text = gtk_entry_get_text (GTK_ENTRY (d_entry));
22448f
+  vinagre_cache_prefs_set_string  ("rdp-connection", "domain", text);
22448f
+
22448f
+  g_object_set (conn,
22448f
+		"domain", text != NULL && *text != '\0' ? text : NULL,
22448f
+		NULL);
22448f
+
22448f
 
22448f
   u_entry = g_object_get_data (G_OBJECT (widget), "username_entry");
22448f
   if (!u_entry)
22448f
diff --git a/plugins/rdp/vinagre-rdp-plugin.c b/plugins/rdp/vinagre-rdp-plugin.c
22448f
index 3929065..dae9ed3 100644
22448f
--- a/plugins/rdp/vinagre-rdp-plugin.c
22448f
+++ b/plugins/rdp/vinagre-rdp-plugin.c
22448f
@@ -100,7 +100,7 @@ vinagre_rdp_plugin_init (VinagreRdpPlugin *plugin)
22448f
 static GtkWidget *
22448f
 impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
22448f
 {
22448f
-  GtkWidget *grid, *label, *u_entry, *spin_button;
22448f
+  GtkWidget *grid, *label, *u_entry, *d_entry, *spin_button, *check;
22448f
   gchar     *str;
22448f
   gint       width, height;
22448f
 
22448f
@@ -134,10 +134,29 @@ impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
22448f
   g_free (str);
22448f
 
22448f
 
22448f
+  label = gtk_label_new_with_mnemonic (_("_Domain:"));
22448f
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
22448f
+  gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
22448f
+  gtk_widget_set_margin_left (label, 12);
22448f
+
22448f
+  d_entry = gtk_entry_new ();
22448f
+  /* Translators: This is the tooltip for the domain field in a RDP connection */
22448f
+  gtk_widget_set_tooltip_text (d_entry, _("Optional."));
22448f
+  g_object_set_data (G_OBJECT (grid), "domain_entry", d_entry);
22448f
+  gtk_grid_attach (GTK_GRID (grid), d_entry, 1, 3, 1, 1);
22448f
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), d_entry);
22448f
+  str = g_strdup (VINAGRE_IS_CONNECTION (conn) ?
22448f
+		  vinagre_connection_get_domain (conn) :
22448f
+		  vinagre_cache_prefs_get_string  ("rdp-connection", "domain", ""));
22448f
+  gtk_entry_set_text (GTK_ENTRY (d_entry), str);
22448f
+  gtk_entry_set_activates_default (GTK_ENTRY (d_entry), TRUE);
22448f
+  g_free (str);
22448f
+
22448f
+
22448f
   /* Host width */
22448f
   label = gtk_label_new_with_mnemonic (_("_Width:"));
22448f
   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
22448f
-  gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
22448f
+  gtk_grid_attach (GTK_GRID (grid), label, 0, 4, 1, 1);
22448f
   gtk_widget_set_margin_left (label, 12);
22448f
 
22448f
   spin_button = gtk_spin_button_new_with_range (MIN_SIZE, MAX_SIZE, 1);
22448f
@@ -145,7 +164,7 @@ impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
22448f
   gtk_widget_set_tooltip_text (spin_button, _("Set width of the remote desktop"));
22448f
   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), DEFAULT_WIDTH);
22448f
   g_object_set_data (G_OBJECT (grid), "width_spin_button", spin_button);
22448f
-  gtk_grid_attach (GTK_GRID (grid), spin_button, 1, 2, 1, 1);
22448f
+  gtk_grid_attach (GTK_GRID (grid), spin_button, 1, 4, 1, 1);
22448f
   gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button);
22448f
   width = VINAGRE_IS_CONNECTION (conn) ?
22448f
           vinagre_connection_get_width (conn) :
22448f
@@ -157,7 +176,7 @@ impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
22448f
   /* Host height */
22448f
   label = gtk_label_new_with_mnemonic (_("_Height:"));
22448f
   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
22448f
-  gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
22448f
+  gtk_grid_attach (GTK_GRID (grid), label, 0, 5, 1, 1);
22448f
   gtk_widget_set_margin_left (label, 12);
22448f
 
22448f
   spin_button = gtk_spin_button_new_with_range (MIN_SIZE, MAX_SIZE, 1);
22448f
@@ -165,7 +184,7 @@ impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
22448f
   gtk_widget_set_tooltip_text (spin_button, _("Set height of the remote desktop"));
22448f
   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), DEFAULT_HEIGHT);
22448f
   g_object_set_data (G_OBJECT (grid), "height_spin_button", spin_button);
22448f
-  gtk_grid_attach (GTK_GRID (grid), spin_button, 1, 3, 1, 1);
22448f
+  gtk_grid_attach (GTK_GRID (grid), spin_button, 1, 5, 1, 1);
22448f
   gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button);
22448f
   height = VINAGRE_IS_CONNECTION (conn) ?
22448f
            vinagre_connection_get_height (conn) :
22448f
diff --git a/plugins/rdp/vinagre-rdp-tab.c b/plugins/rdp/vinagre-rdp-tab.c
22448f
index c4c11f8..90eea1c 100644
22448f
--- a/plugins/rdp/vinagre-rdp-tab.c
22448f
+++ b/plugins/rdp/vinagre-rdp-tab.c
22448f
@@ -62,6 +62,13 @@ struct _VinagreRdpTabPrivate
22448f
   guint            key_press_handler_id;
22448f
   guint            key_release_handler_id;
22448f
   guint            motion_notify_handler_id;
22448f
+
22448f
+  GSList          *connected_actions;
22448f
+  double           scale;
22448f
+  double           offset_x, offset_y;
22448f
+
22448f
+  guint            authentication_attempts;
22448f
+  gboolean         authentication_cancelled;
22448f
 };
22448f
 
22448f
 G_DEFINE_TYPE (VinagreRdpTab, vinagre_rdp_tab, VINAGRE_TYPE_TAB)
22448f
@@ -391,6 +398,7 @@ frdp_post_connect (freerdp *instance)
22448f
                               0, 0,
22448f
                               gdi->width, gdi->height);
22448f
 
22448f
+  vinagre_tab_save_credentials_in_keyring (VINAGRE_TAB (rdp_tab));
22448f
   vinagre_tab_add_recent_used (VINAGRE_TAB (rdp_tab));
22448f
   vinagre_tab_set_state (VINAGRE_TAB (rdp_tab), VINAGRE_TAB_STATE_CONNECTED);
22448f
 
22448f
@@ -633,114 +641,77 @@ frdp_mouse_moved (GtkWidget      *widget,
22448f
   return TRUE;
22448f
 }
22448f
 
22448f
-static void
22448f
-entry_text_changed_cb (GtkEntry   *entry,
22448f
-                       GtkBuilder *builder)
22448f
-{
22448f
-  const gchar *text;
22448f
-  GtkWidget   *widget;
22448f
-  gsize        username_length;
22448f
-  gsize        password_length;
22448f
-
22448f
-  widget = GTK_WIDGET (gtk_builder_get_object (builder, "username_entry"));
22448f
-  text = gtk_entry_get_text (GTK_ENTRY (widget));
22448f
-  username_length = strlen (text);
22448f
-
22448f
-  widget = GTK_WIDGET (gtk_builder_get_object (builder, "password_entry"));
22448f
-  text = gtk_entry_get_text (GTK_ENTRY (widget));
22448f
-  password_length = strlen (text);
22448f
-
22448f
-  widget = GTK_WIDGET (gtk_builder_get_object (builder, "ok_button"));
22448f
-  gtk_widget_set_sensitive (widget, password_length > 0 && username_length > 0);
22448f
-}
22448f
-
22448f
 static gboolean
22448f
 frdp_authenticate (freerdp  *instance,
22448f
                    char    **username,
22448f
                    char    **password,
22448f
                    char    **domain)
22448f
 {
22448f
-  VinagreTab        *tab = VINAGRE_TAB (((frdpContext *) instance->context)->rdp_tab);
22448f
-  VinagreConnection *conn = vinagre_tab_get_conn (tab);
22448f
-  const gchar       *user_name;
22448f
-  const gchar       *domain_name;
22448f
-  GtkBuilder        *builder;
22448f
-  GtkWidget         *dialog;
22448f
-  GtkWidget         *widget;
22448f
-  GtkWidget         *username_entry;
22448f
-  GtkWidget         *password_entry;
22448f
-  GtkWidget         *domain_entry;
22448f
-  gboolean           save_credential_check_visible;
22448f
-  gboolean           domain_label_visible;
22448f
-  gboolean           domain_entry_visible;
22448f
-  gint               response;
22448f
-
22448f
-  builder = vinagre_utils_get_builder ();
22448f
-
22448f
-  dialog = GTK_WIDGET (gtk_builder_get_object (builder, "auth_required_dialog"));
22448f
-  gtk_window_set_modal ((GtkWindow *) dialog, TRUE);
22448f
-  gtk_window_set_transient_for ((GtkWindow *) dialog, GTK_WINDOW (vinagre_tab_get_window (tab)));
22448f
-
22448f
-  widget = GTK_WIDGET (gtk_builder_get_object (builder, "host_label"));
22448f
-  gtk_label_set_text (GTK_LABEL (widget), vinagre_connection_get_host (conn));
22448f
+  VinagreTab           *tab = VINAGRE_TAB (((frdpContext *) instance->context)->rdp_tab);
22448f
+  VinagreRdpTab        *rdp_tab = VINAGRE_RDP_TAB (tab);
22448f
+  VinagreRdpTabPrivate *priv = rdp_tab->priv;
22448f
+  VinagreConnection    *conn = vinagre_tab_get_conn (tab);
22448f
+  GtkWindow            *window = GTK_WINDOW (vinagre_tab_get_window (tab));
22448f
+  gboolean              save_in_keyring = FALSE;
22448f
+  gchar                *keyring_domain = NULL;
22448f
+  gchar                *keyring_username = NULL;
22448f
+  gchar                *keyring_password = NULL;
22448f
 
22448f
-  username_entry = GTK_WIDGET (gtk_builder_get_object (builder, "username_entry"));
22448f
-  password_entry = GTK_WIDGET (gtk_builder_get_object (builder, "password_entry"));
22448f
-  domain_entry = GTK_WIDGET (gtk_builder_get_object (builder, "domain_entry"));
22448f
+  priv->authentication_attempts++;
22448f
 
22448f
-  if (*username != NULL && *username[0] != '\0')
22448f
+  if (priv->authentication_attempts == 1)
22448f
     {
22448f
-      gtk_entry_set_text (GTK_ENTRY (username_entry), *username);
22448f
-      gtk_widget_grab_focus (password_entry);
22448f
-    }
22448f
-
22448f
-  g_signal_connect (username_entry, "changed", G_CALLBACK (entry_text_changed_cb), builder);
22448f
-  g_signal_connect (password_entry, "changed", G_CALLBACK (entry_text_changed_cb), builder);
22448f
-
22448f
-
22448f
-  widget = GTK_WIDGET (gtk_builder_get_object (builder, "save_credential_check"));
22448f
-  save_credential_check_visible = gtk_widget_get_visible (widget);
22448f
-  gtk_widget_set_visible (widget, FALSE);
22448f
-
22448f
-  widget = GTK_WIDGET (gtk_builder_get_object (builder, "domain_label"));
22448f
-  domain_label_visible = gtk_widget_get_visible (widget);
22448f
-  gtk_widget_set_visible (widget, TRUE);
22448f
-
22448f
-  domain_entry_visible = gtk_widget_get_visible (domain_entry);
22448f
-  gtk_widget_set_visible (domain_entry, TRUE);
22448f
-
22448f
-
22448f
-  response = gtk_dialog_run (GTK_DIALOG (dialog));
22448f
-  gtk_widget_hide (dialog);
22448f
-
22448f
-
22448f
-  widget = GTK_WIDGET (gtk_builder_get_object (builder, "save_credential_check"));
22448f
-  gtk_widget_set_visible (widget, save_credential_check_visible);
22448f
-
22448f
-  widget = GTK_WIDGET (gtk_builder_get_object (builder, "domain_label"));
22448f
-  gtk_widget_set_visible (widget, domain_label_visible);
22448f
-
22448f
-  gtk_widget_set_visible (domain_entry, domain_entry_visible);
22448f
+      vinagre_tab_find_credentials_in_keyring (tab, &keyring_domain, &keyring_username, &keyring_password);
22448f
+      if (keyring_password != NULL && keyring_username != NULL)
22448f
+        {
22448f
+          *domain = keyring_domain;
22448f
+          *username = keyring_username;
22448f
+          *password = keyring_password;
22448f
 
22448f
+          return TRUE;
22448f
+        }
22448f
+      else
22448f
+        {
22448f
+          g_free (keyring_domain);
22448f
+          g_free (keyring_username);
22448f
+          g_free (keyring_password);
22448f
+        }
22448f
+    }
22448f
 
22448f
-  if (response == GTK_RESPONSE_OK)
22448f
+  if (vinagre_utils_request_credential (window,
22448f
+                                        "RDP",
22448f
+                                        vinagre_connection_get_host (conn),
22448f
+                                        vinagre_connection_get_domain (conn),
22448f
+                                        vinagre_connection_get_username (conn),
22448f
+                                        TRUE,
22448f
+                                        TRUE,
22448f
+                                        TRUE,
22448f
+                                        20,
22448f
+                                        domain,
22448f
+                                        username,
22448f
+                                        password,
22448f
+                                        &save_in_keyring))
22448f
     {
22448f
-      domain_name = gtk_entry_get_text (GTK_ENTRY (domain_entry));
22448f
-      if (g_strcmp0 (*domain, domain_name) != 0)
22448f
-        *domain = g_strdup (domain_name);
22448f
+      if (*domain && **domain != '\0')
22448f
+        vinagre_connection_set_domain (conn, *domain);
22448f
 
22448f
-      user_name = gtk_entry_get_text (GTK_ENTRY (username_entry));
22448f
-      if (g_strcmp0 (*username, user_name) != 0)
22448f
-        *username = g_strdup (user_name);
22448f
+      if (*username && **username != '\0')
22448f
+        vinagre_connection_set_username (conn, *username);
22448f
 
22448f
-      *password = g_strdup (gtk_entry_get_text (GTK_ENTRY (password_entry)));
22448f
+      if (*password && **password != '\0')
22448f
+        vinagre_connection_set_password (conn, *password);
22448f
 
22448f
-      return TRUE;
22448f
+      vinagre_tab_set_save_credentials (tab, save_in_keyring);
22448f
     }
22448f
   else
22448f
     {
22448f
+      vinagre_tab_remove_from_notebook (tab);
22448f
+      priv->authentication_cancelled = TRUE;
22448f
+
22448f
       return FALSE;
22448f
     }
22448f
+
22448f
+  return TRUE;
22448f
 }
22448f
 
22448f
 static BOOL
22448f
@@ -837,29 +808,23 @@ frdp_changed_certificate_verify (freerdp *instance,
22448f
 #endif
22448f
 
22448f
 static void
22448f
-open_freerdp (VinagreRdpTab *rdp_tab)
22448f
+init_freerdp (VinagreRdpTab *rdp_tab)
22448f
 {
22448f
   VinagreRdpTabPrivate *priv = rdp_tab->priv;
22448f
+  rdpSettings          *settings;
22448f
   VinagreTab           *tab = VINAGRE_TAB (rdp_tab);
22448f
   VinagreConnection    *conn = vinagre_tab_get_conn (tab);
22448f
-  rdpSettings          *settings;
22448f
-  GtkWindow            *window = GTK_WINDOW (vinagre_tab_get_window (tab));
22448f
-  gboolean              success = TRUE;
22448f
-  gboolean              fullscreen;
22448f
-  gchar                *hostname, *username;
22448f
-  gint                  port, width, height;
22448f
+  gchar                *hostname;
22448f
+  gint                  width, height;
22448f
+  gint                  port;
22448f
 
22448f
   g_object_get (conn,
22448f
                 "port", &port,
22448f
                 "host", &hostname,
22448f
                 "width", &width,
22448f
                 "height", &height,
22448f
-                "fullscreen", &fullscreen,
22448f
-                "username", &username,
22448f
                 NULL);
22448f
 
22448f
-  priv->events = g_queue_new ();
22448f
-
22448f
   /* Setup FreeRDP session */
22448f
   priv->freerdp_session = freerdp_new ();
22448f
   priv->freerdp_session->PreConnect = frdp_pre_connect;
22448f
@@ -919,23 +884,29 @@ open_freerdp (VinagreRdpTab *rdp_tab)
22448f
   settings->port = port;
22448f
 #endif
22448f
 
22448f
-  /* Set username */
22448f
-  username = g_strstrip (username);
22448f
-  if (username != NULL && username[0] != '\0')
22448f
-    {
22448f
-#if HAVE_FREERDP_1_1
22448f
-      settings->Username = g_strdup (username);
22448f
-#else
22448f
-      settings->username = g_strdup (username);
22448f
-#endif
22448f
-    }
22448f
-
22448f
   /* Set keyboard layout */
22448f
 #if HAVE_FREERDP_1_1
22448f
   freerdp_keyboard_init (KBD_US);
22448f
 #else
22448f
   freerdp_kbd_init (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), KBD_US);
22448f
 #endif
22448f
+}
22448f
+
22448f
+static void
22448f
+init_display (VinagreRdpTab *rdp_tab)
22448f
+{
22448f
+  VinagreRdpTabPrivate *priv = rdp_tab->priv;
22448f
+  VinagreTab           *tab = VINAGRE_TAB (rdp_tab);
22448f
+  VinagreConnection    *conn = vinagre_tab_get_conn (tab);
22448f
+  GtkWindow            *window = GTK_WINDOW (vinagre_tab_get_window (tab));
22448f
+  gboolean              fullscreen;
22448f
+  gint                  width, height;
22448f
+
22448f
+  g_object_get (conn,
22448f
+                "width", &width,
22448f
+                "height", &height,
22448f
+                "fullscreen", &fullscreen,
22448f
+                NULL);
22448f
 
22448f
   /* Setup display for FreeRDP session */
22448f
   priv->display = gtk_drawing_area_new ();
22448f
@@ -984,22 +955,52 @@ open_freerdp (VinagreRdpTab *rdp_tab)
22448f
   priv->key_release_handler_id = g_signal_connect (window, "key-release-event",
22448f
                                                    G_CALLBACK (frdp_key_pressed),
22448f
                                                    rdp_tab);
22448f
+}
22448f
 
22448f
-  /* Run FreeRDP session */
22448f
-  success = freerdp_connect (priv->freerdp_session);
22448f
+static void
22448f
+open_freerdp (VinagreRdpTab *rdp_tab)
22448f
+{
22448f
+  VinagreRdpTabPrivate *priv = rdp_tab->priv;
22448f
+  VinagreTab           *tab = VINAGRE_TAB (rdp_tab);
22448f
+  GtkWindow            *window = GTK_WINDOW (vinagre_tab_get_window (tab));
22448f
+  gboolean              success = TRUE;
22448f
+
22448f
+  priv->events = g_queue_new ();
22448f
+
22448f
+  init_freerdp (rdp_tab);
22448f
+  init_display (rdp_tab);
22448f
+  priv->authentication_cancelled = FALSE;
22448f
+
22448f
+  do
22448f
+    {
22448f
+      /* Run FreeRDP session */
22448f
+      success = freerdp_connect (priv->freerdp_session);
22448f
+      if (!success)
22448f
+        {
22448f
+          freerdp_free (priv->freerdp_session);
22448f
+          init_freerdp (rdp_tab);
22448f
+        }
22448f
+    }
22448f
+  while (!success &&
22448f
+         priv->authentication_attempts > 3 &&
22448f
+         !priv->authentication_cancelled);
22448f
 
22448f
   if (!success)
22448f
     {
22448f
       gtk_window_unfullscreen (window);
22448f
-      vinagre_utils_show_error_dialog (_("Error connecting to host."),
22448f
-                                       NULL,
22448f
-                                       window);
22448f
+      if (!priv->authentication_cancelled)
22448f
+        vinagre_utils_show_error_dialog (_("Error connecting to host."),
22448f
+                                         NULL,
22448f
+                                         window);
22448f
       g_idle_add ((GSourceFunc) idle_close, rdp_tab);
22448f
     }
22448f
   else
22448f
     {
22448f
+      priv->authentication_attempts = 0;
22448f
       priv->update_id = g_idle_add ((GSourceFunc) update, rdp_tab);
22448f
     }
22448f
+
22448f
+  priv->authentication_attempts = 0;
22448f
 }
22448f
 
22448f
 static void
22448f
-- 
22448f
2.5.5
22448f