Blob Blame History Raw
From 503a7925fcd71e7826322d32d4af6d1a36e2f03c Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Fri, 20 Nov 2015 17:32:58 +0100
Subject: [PATCH 1/2] Handle domain when looking for credentials

Add domain property to VinagreConnection and use it when looking for
credentials if needed.
Show default values for 'username' and 'domain' in authentication dialog
if given.

https://bugzilla.gnome.org/show_bug.cgi?id=753355
---
 data/vinagre.ui                   |   6 +--
 plugins/spice/vinagre-spice-tab.c |   4 ++
 plugins/vnc/vinagre-vnc-tab.c     |   6 +--
 vinagre/vinagre-connection.c      |  44 +++++++++++++++++
 vinagre/vinagre-connection.h      |   4 ++
 vinagre/vinagre-ssh.c             |   4 +-
 vinagre/vinagre-tab.c             | 100 ++++++++++++++++++++++++++++----------
 vinagre/vinagre-tab.h             |   1 +
 vinagre/vinagre-utils.vala        |  34 +++++++++++++
 9 files changed, 169 insertions(+), 34 deletions(-)

diff --git a/data/vinagre.ui b/data/vinagre.ui
index 8b3e7f3..3135336 100644
--- a/data/vinagre.ui
+++ b/data/vinagre.ui
@@ -207,7 +207,7 @@ Jonh Wendell &lt;jwendell@gnome.org&gt;</property>
                 </child>
                 <child>
                   <object class="GtkLabel" id="domain_label">
-                    <property name="visible">False</property>
+                    <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <property name="margin_left">12</property>
@@ -240,7 +240,7 @@ Jonh Wendell &lt;jwendell@gnome.org&gt;</property>
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
-                    <property name="top_attach">3</property>
+                    <property name="top_attach">4</property>
                     <property name="width">1</property>
                     <property name="height">1</property>
                   </packing>
@@ -281,7 +281,7 @@ Jonh Wendell &lt;jwendell@gnome.org&gt;</property>
                 </child>
                 <child>
                   <object class="GtkEntry" id="domain_entry">
-                    <property name="visible">False</property>
+                    <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <property name="max_length">254</property>
diff --git a/plugins/spice/vinagre-spice-tab.c b/plugins/spice/vinagre-spice-tab.c
index 0a26a00..2c20477 100644
--- a/plugins/spice/vinagre-spice-tab.c
+++ b/plugins/spice/vinagre-spice-tab.c
@@ -297,10 +297,14 @@ spice_main_channel_event_cb(SpiceChannel *channel, SpiceChannelEvent event,
     if (!vinagre_utils_request_credential (window,
 				       "SPICE",
 				       name,
+				       NULL,
+				       NULL,
+				       FALSE,
 				       FALSE,
 				       TRUE,
 				       SPICE_MAX_PASSWORD_LENGTH,
 				       NULL,
+				       NULL,
 				       &password,
 				       &save_in_keyring))
       {
diff --git a/plugins/vnc/vinagre-vnc-tab.c b/plugins/vnc/vinagre-vnc-tab.c
index cf675a5..a3bc467 100644
--- a/plugins/vnc/vinagre-vnc-tab.c
+++ b/plugins/vnc/vinagre-vnc-tab.c
@@ -502,13 +502,13 @@ vnc_authentication_cb (VncDisplay *vnc, GValueArray *credList, VinagreVncTab *vn
 
   if (need_password || need_username)
     {
-      vinagre_tab_find_credentials_in_keyring (tab, &username, &password);
+      vinagre_tab_find_credentials_in_keyring (tab, NULL, &username, &password);
 
       if ( (need_username && !username) || (need_password && !password) )
 	{
 	  host = vinagre_connection_get_best_name (conn);
-	  if (!vinagre_utils_request_credential (window, "VNC", host,
-	     need_username, need_password, 8, &username, &password,
+	  if (!vinagre_utils_request_credential (window, "VNC", host, NULL, NULL,
+	     FALSE, need_username, need_password, 8, NULL, &username, &password,
 	     &save_in_keyring))
 	    {
 	      vinagre_tab_remove_from_notebook (tab);
diff --git a/vinagre/vinagre-connection.c b/vinagre/vinagre-connection.c
index 3a3b9ac..23c21c2 100644
--- a/vinagre/vinagre-connection.c
+++ b/vinagre/vinagre-connection.c
@@ -39,6 +39,7 @@ struct _VinagreConnectionPrivate
   gchar *protocol;
   gchar *host;
   gint   port;
+  gchar *domain;
   gchar *username;
   gchar *password;
   gchar *name;
@@ -53,6 +54,7 @@ enum
   PROP_PROTOCOL,
   PROP_HOST,
   PROP_PORT,
+  PROP_DOMAIN,
   PROP_USERNAME,
   PROP_PASSWORD,
   PROP_NAME,
@@ -75,6 +77,7 @@ vinagre_connection_init (VinagreConnection *conn)
   conn->priv->port = 0;
   conn->priv->password = NULL;
   conn->priv->username = NULL;
+  conn->priv->domain = NULL;
   conn->priv->name = NULL;
   conn->priv->fullscreen = FALSE;
   conn->priv->width = DEFAULT_WIDTH;
@@ -88,6 +91,7 @@ vinagre_connection_finalize (GObject *object)
 
   g_free (conn->priv->protocol);
   g_free (conn->priv->host);
+  g_free (conn->priv->domain);
   g_free (conn->priv->username);
   g_free (conn->priv->password);
   g_free (conn->priv->name);
@@ -118,6 +122,10 @@ vinagre_connection_set_property (GObject *object, guint prop_id, const GValue *v
 	vinagre_connection_set_port (conn, g_value_get_int (value));
 	break;
 
+      case PROP_DOMAIN:
+	vinagre_connection_set_domain (conn, g_value_get_string (value));
+	break;
+
       case PROP_USERNAME:
 	vinagre_connection_set_username (conn, g_value_get_string (value));
 	break;
@@ -172,6 +180,10 @@ vinagre_connection_get_property (GObject *object, guint prop_id, GValue *value,
 	g_value_set_int (value, conn->priv->port);
 	break;
 
+      case PROP_DOMAIN:
+	g_value_set_string (value, conn->priv->domain);
+	break;
+
       case PROP_USERNAME:
 	g_value_set_string (value, conn->priv->username);
 	break;
@@ -214,6 +226,7 @@ default_fill_writer (VinagreConnection *conn, xmlTextWriter *writer)
   xmlTextWriterWriteElement (writer, BAD_CAST "name", BAD_CAST conn->priv->name);
   xmlTextWriterWriteElement (writer, BAD_CAST "host", BAD_CAST conn->priv->host);
   xmlTextWriterWriteElement (writer, BAD_CAST "username", BAD_CAST (conn->priv->username ? conn->priv->username : ""));
+  xmlTextWriterWriteElement (writer, BAD_CAST "domain", BAD_CAST (conn->priv->domain ? conn->priv->domain : ""));
   xmlTextWriterWriteFormatElement (writer, BAD_CAST "port", "%d", conn->priv->port);
   xmlTextWriterWriteFormatElement (writer, BAD_CAST "fullscreen", "%d", conn->priv->fullscreen);
   xmlTextWriterWriteFormatElement (writer, BAD_CAST "width", "%d", conn->priv->width);
@@ -236,6 +249,8 @@ default_parse_item (VinagreConnection *conn, xmlNode *root)
 	vinagre_connection_set_name (conn, (const gchar *)s_value);
       else if (!xmlStrcmp(curr->name, BAD_CAST "username"))
 	vinagre_connection_set_username (conn, (const gchar *)s_value);
+      else if (!xmlStrcmp(curr->name, BAD_CAST "domain"))
+	vinagre_connection_set_domain (conn, (const gchar *)s_value);
       else if (!xmlStrcmp(curr->name, BAD_CAST "port"))
 	vinagre_connection_set_port (conn, atoi ((const char *)s_value));
       else if (!xmlStrcmp(curr->name, BAD_CAST "fullscreen"))
@@ -322,6 +337,18 @@ vinagre_connection_class_init (VinagreConnectionClass *klass)
                                                       G_PARAM_STATIC_BLURB));
 
   g_object_class_install_property (object_class,
+                                   PROP_DOMAIN,
+                                   g_param_spec_string ("domain",
+                                                        "domain",
+                                                        "domain (if any) necessary for complete this connection",
+                                                        NULL,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (object_class,
                                    PROP_USERNAME,
                                    g_param_spec_string ("username",
                                                         "username",
@@ -460,6 +487,23 @@ vinagre_connection_get_port (VinagreConnection *conn)
 }
 
 void
+vinagre_connection_set_domain (VinagreConnection *conn,
+			       const gchar *domain)
+{
+  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
+
+  g_free (conn->priv->domain);
+  conn->priv->domain = g_strdup (domain);
+}
+const gchar *
+vinagre_connection_get_domain (VinagreConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
+
+  return conn->priv->domain;
+}
+
+void
 vinagre_connection_set_username (VinagreConnection *conn,
 				 const gchar *username)
 {
diff --git a/vinagre/vinagre-connection.h b/vinagre/vinagre-connection.h
index 7fc130c..a717208 100644
--- a/vinagre/vinagre-connection.h
+++ b/vinagre/vinagre-connection.h
@@ -72,6 +72,10 @@ gint		    vinagre_connection_get_port		(VinagreConnection *conn);
 void		    vinagre_connection_set_port		(VinagreConnection *conn,
 							 gint port);
 
+const gchar*	    vinagre_connection_get_domain	(VinagreConnection *conn);
+void		    vinagre_connection_set_domain	(VinagreConnection *conn,
+							 const gchar *domain);
+
 const gchar*	    vinagre_connection_get_username	(VinagreConnection *conn);
 void		    vinagre_connection_set_username	(VinagreConnection *conn,
 							 const gchar *username);
diff --git a/vinagre/vinagre-ssh.c b/vinagre/vinagre-ssh.c
index 432563b..7db228f 100644
--- a/vinagre/vinagre-ssh.c
+++ b/vinagre/vinagre-ssh.c
@@ -502,8 +502,8 @@ handle_login (GtkWindow *parent,
 	      gboolean res;
 
 	      full_host = g_strjoin ("@", user, host, NULL);
-	      res = vinagre_utils_request_credential (parent, "SSH", full_host,
-		  FALSE, TRUE, 0, NULL, &password, &save_in_keyring);
+	      res = vinagre_utils_request_credential (parent, "SSH", full_host, NULL, NULL,
+		  FALSE, FALSE, TRUE, 0, NULL, NULL, &password, &save_in_keyring);
 	      g_free (full_host);
               if (!res)
                 {
diff --git a/vinagre/vinagre-tab.c b/vinagre/vinagre-tab.c
index f19bfe5..1ac123a 100644
--- a/vinagre/vinagre-tab.c
+++ b/vinagre/vinagre-tab.c
@@ -758,24 +758,71 @@ vinagre_tab_get_from_connection (VinagreConnection *conn)
   return (res != NULL) ? VINAGRE_TAB (res) : NULL;
 }
 
+static GHashTable *
+secret_attributes_create (VinagreConnection *connection)
+{
+  const gchar *conn_user = vinagre_connection_get_username (connection);
+  const gchar *conn_domain = vinagre_connection_get_domain (connection);
+  GHashTable  *attributes;
+
+  attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+  g_hash_table_insert (attributes,
+                       g_strdup ("server"),
+                       g_strdup (vinagre_connection_get_host (connection)));
+
+  g_hash_table_insert (attributes,
+                       g_strdup ("protocol"),
+                       g_strdup (vinagre_connection_get_protocol (connection)));
+
+  g_hash_table_insert (attributes,
+                       g_strdup ("port"),
+                       g_strdup_printf ("%d", vinagre_connection_get_port (connection)));
+
+  if (conn_user != NULL)
+    {
+      g_hash_table_insert (attributes,
+                           g_strdup ("user"),
+                           g_strdup (conn_user));
+    }
+
+  if (conn_domain != NULL)
+    {
+      g_hash_table_insert (attributes,
+                           g_strdup ("domain"),
+                           g_strdup (conn_domain));
+    }
+
+  return attributes;
+}
+
 gboolean
-vinagre_tab_find_credentials_in_keyring (VinagreTab *tab, gchar **username, gchar **password)
+vinagre_tab_find_credentials_in_keyring (VinagreTab *tab, gchar **domain, gchar **username, gchar **password)
 {
   const gchar *conn_user = vinagre_connection_get_username (tab->priv->conn);
+  const gchar *conn_domain = vinagre_connection_get_domain (tab->priv->conn);
+  GHashTable  *attributes;
+
   *username = NULL;
 
-  /* "user" goes last, to terminate the attribute list if conn_user is NULL. */
-  *password = secret_password_lookup_sync (SECRET_SCHEMA_COMPAT_NETWORK, NULL, NULL,
-                                           "server", vinagre_connection_get_host (tab->priv->conn),
-                                           "protocol", vinagre_connection_get_protocol (tab->priv->conn),
-                                           "port", vinagre_connection_get_port (tab->priv->conn),
-                                           conn_user ? "user" : NULL, conn_user,
-                                           NULL);
+  if (domain != NULL)
+    *domain = NULL;
+
+  attributes = secret_attributes_create (tab->priv->conn);
+
+  *password = secret_password_lookupv_sync (SECRET_SCHEMA_COMPAT_NETWORK,
+                                            attributes, NULL, NULL);
+
+  g_hash_table_destroy (attributes);
 
   if (*password == NULL)
     return FALSE;
 
   *username = g_strdup (conn_user);
+
+  if (domain != NULL)
+    *domain = g_strdup (conn_domain);
+
   return TRUE;
 }
 
@@ -787,25 +834,24 @@ void vinagre_tab_set_save_credentials (VinagreTab *tab, gboolean value)
 void
 vinagre_tab_save_credentials_in_keyring (VinagreTab *tab)
 {
+  GHashTable *attributes;
   GError *error = NULL;
   gchar *label;
-  const gchar *conn_user = vinagre_connection_get_username (tab->priv->conn);
 
   if (!tab->priv->save_credentials)
     return;
 
   label = g_strdup_printf (_("Remote desktop password for %s"),
                            vinagre_connection_get_host (tab->priv->conn));
-  /* "user" goes last, to terminate the attribute list if conn_user is NULL. */
-  secret_password_store_sync (SECRET_SCHEMA_COMPAT_NETWORK, NULL,
-                              label, vinagre_connection_get_password (tab->priv->conn),
-                              NULL, &error,
-                              "server", vinagre_connection_get_host (tab->priv->conn),
-                              "protocol", vinagre_connection_get_protocol (tab->priv->conn),
-                              "port", vinagre_connection_get_port (tab->priv->conn),
-                              conn_user ? "user" : NULL, conn_user,
-                              NULL);
+
+  attributes = secret_attributes_create (tab->priv->conn);
+
+  secret_password_storev_sync (SECRET_SCHEMA_COMPAT_NETWORK, attributes, NULL,
+                               label, vinagre_connection_get_password (tab->priv->conn),
+                               NULL, &error);
+
   g_free (label);
+  g_hash_table_destroy (attributes);
 
   if (error == NULL) {
     tab->priv->saved_credentials = TRUE;
@@ -824,17 +870,19 @@ void vinagre_tab_remove_credentials_from_keyring (VinagreTab *tab)
 {
   if (tab->priv->saved_credentials)
     {
-      /* Put "user" last, to terminate the attributes if conn_user is NULL. */
-      const gchar *conn_user = vinagre_connection_get_username (tab->priv->conn);
-      secret_password_clear_sync (SECRET_SCHEMA_COMPAT_NETWORK, NULL, NULL,
-                                  "server", vinagre_connection_get_host (tab->priv->conn),
-                                  "protocol", vinagre_connection_get_protocol (tab->priv->conn),
-                                  "port", vinagre_connection_get_port (tab->priv->conn),
-                                  conn_user ? "user" : NULL, conn_user,
-                                  NULL);
+      GHashTable *attributes;
+
+      attributes = secret_attributes_create (tab->priv->conn);
+
+      secret_password_clearv_sync (SECRET_SCHEMA_COMPAT_NETWORK,
+                                   attributes, NULL, NULL);
+
       tab->priv->saved_credentials = FALSE;
+
+      g_hash_table_destroy (attributes);
     }
 
+  vinagre_connection_set_domain (tab->priv->conn, NULL);
   vinagre_connection_set_username (tab->priv->conn, NULL);
   vinagre_connection_set_password (tab->priv->conn, NULL);
 }
diff --git a/vinagre/vinagre-tab.h b/vinagre/vinagre-tab.h
index 01bd36b..58f7275 100644
--- a/vinagre/vinagre-tab.h
+++ b/vinagre/vinagre-tab.h
@@ -127,6 +127,7 @@ const gchar		*vinagre_tab_get_icon_name	(VinagreTab *tab);
 void			vinagre_tab_set_save_credentials	(VinagreTab *tab, gboolean value);
 void			vinagre_tab_save_credentials_in_keyring (VinagreTab *tab);
 gboolean		vinagre_tab_find_credentials_in_keyring	(VinagreTab *tab,
+								 gchar **domain,
 								 gchar **username,
 								 gchar **password);
 void			vinagre_tab_remove_credentials_from_keyring (VinagreTab *tab);
diff --git a/vinagre/vinagre-utils.vala b/vinagre/vinagre-utils.vala
index 15969f4..2d90cb4 100644
--- a/vinagre/vinagre-utils.vala
+++ b/vinagre/vinagre-utils.vala
@@ -95,9 +95,13 @@ namespace Vinagre.Utils {
     public bool request_credential (Window     parent,
                                     string     protocol,
                                     string     host,
+                                    string?    default_domain,
+                                    string?    default_username,
+                                    bool       need_domain,
                                     bool       need_username,
                                     bool       need_password,
                                     int        password_limit,
+                                    out string domain,
                                     out string username,
                                     out string password,
                                     out bool   save_in_keyring)
@@ -116,6 +120,7 @@ namespace Vinagre.Utils {
 
         var password_label = xml.get_object ("password_label") as Label;
         var username_label = xml.get_object ("username_label") as Label;
+        var domain_label = xml.get_object ("domain_label") as Label;
         var save_credential_check = xml.get_object ("save_credential_check")
                                     as CheckButton;
 
@@ -124,9 +129,30 @@ namespace Vinagre.Utils {
                                           IconSize.BUTTON);
         ok_button.image = image;
 
+        var domain_entry = xml.get_object ("domain_entry") as Entry;
         var username_entry = xml.get_object ("username_entry") as Entry;
         var password_entry = xml.get_object ("password_entry") as Entry;
 
+        domain_entry.changed.connect (() => {
+            var enabled = true;
+
+            if (username_entry.visible)
+                enabled = enabled && username_entry.text_length > 0;
+
+            if (password_entry.visible)
+                enabled = enabled && password_entry.text_length > 0;
+
+            ok_button.sensitive = enabled;
+        });
+
+        if (!need_domain) {
+            domain_label.hide ();
+            domain_entry.hide ();
+        } else {
+            if (default_domain != null)
+                domain_entry.set_text (default_domain);
+        }
+
         username_entry.changed.connect (() => {
             var enabled = true;
 
@@ -142,6 +168,11 @@ namespace Vinagre.Utils {
         if (!need_username) {
             username_label.hide ();
             username_entry.hide ();
+        } else {
+            if (default_username != null) {
+                username_entry.set_text (default_username);
+                password_entry.grab_focus ();
+            }
         }
 
         password_entry.changed.connect (() => {
@@ -165,6 +196,9 @@ namespace Vinagre.Utils {
 
         var result = password_dialog.run ();
         if (result == ResponseType.OK) {
+            if (domain_entry.text_length > 0)
+                domain = domain_entry.text;
+
             if (username_entry.text_length > 0)
                 username = username_entry.text;
 
-- 
2.5.0