[gnome-remote-desktop] Introduce GrdCredentials



commit f6317b8e789a151291f3bdafff090f2901128747
Author: Jonas Ådahl <jadahl gmail com>
Date:   Tue Jun 21 11:50:31 2022 +0200

    Introduce GrdCredentials
    
    This type aims to provide an abstraction level above credentials
    management, so that they can be handled differently depending on in what
    way the daemon is run.
    
    For now, the only added backend is one using libsecret, and it is
    identical to the existing libsecret implementation. Every user that used
    libsecret directly now access the credentials via the abstracted API.
    
    This changes the stored format when using the VNC backend. To handle
    this, change the Secret schema name, and migrate from the old format
    whenever the Secret credentials instance is created, i.e. either before
    initializing the daemon, or before running any grdctl command.

 src/grd-context.c                                  |  13 +-
 src/grd-context.h                                  |   2 +
 src/grd-credentials-libsecret.c                    | 240 +++++++++++++++++++++
 src/{grd-schemas.h => grd-credentials-libsecret.h} |  18 +-
 src/grd-credentials.c                              |  63 ++++++
 src/grd-credentials.h                              |  67 ++++++
 src/grd-ctl.c                                      |  89 ++++----
 src/grd-schemas.c                                  |  54 -----
 src/grd-session-rdp.c                              |  14 +-
 src/grd-settings.c                                 | 134 ++++++------
 src/grd-settings.h                                 |  13 +-
 src/grd-types.h                                    |   1 +
 src/meson.build                                    |  14 +-
 13 files changed, 524 insertions(+), 198 deletions(-)
---
diff --git a/src/grd-context.c b/src/grd-context.c
index 7bf2930e..7f45988e 100644
--- a/src/grd-context.c
+++ b/src/grd-context.c
@@ -24,7 +24,9 @@
 
 #include "grd-context.h"
 
+#include "grd-credentials-libsecret.h"
 #include "grd-egl-thread.h"
+#include "grd-settings.h"
 
 #include "grd-dbus-remote-desktop.h"
 #include "grd-dbus-screen-cast.h"
@@ -42,6 +44,7 @@ struct _GrdContext
 
   GrdEglThread *egl_thread;
 
+  GrdCredentials *credentials;
   GrdSettings *settings;
 
   GrdDebugFlags debug_flags;
@@ -83,6 +86,12 @@ grd_context_get_settings (GrdContext *context)
   return context->settings;
 }
 
+GrdCredentials *
+grd_context_get_credentials (GrdContext *context)
+{
+  return context->credentials;
+}
+
 GrdEglThread *
 grd_context_get_egl_thread (GrdContext *context)
 {
@@ -132,6 +141,7 @@ grd_context_finalize (GObject *object)
   g_clear_object (&context->screen_cast_proxy);
   g_clear_pointer (&context->egl_thread, grd_egl_thread_free);
   g_clear_object (&context->settings);
+  g_clear_object (&context->credentials);
 
   G_OBJECT_CLASS (grd_context_parent_class)->finalize (object);
 }
@@ -141,7 +151,8 @@ grd_context_init (GrdContext *context)
 {
   init_debug_flags (context);
 
-  context->settings = g_object_new (GRD_TYPE_SETTINGS, NULL);
+  context->credentials = GRD_CREDENTIALS (grd_credentials_libsecret_new ());
+  context->settings = grd_settings_new (context);
 }
 
 static void
diff --git a/src/grd-context.h b/src/grd-context.h
index 24a4432c..2efc4cdb 100644
--- a/src/grd-context.h
+++ b/src/grd-context.h
@@ -51,6 +51,8 @@ void grd_context_set_screen_cast_proxy (GrdContext        *context,
 
 GrdSettings * grd_context_get_settings (GrdContext *context);
 
+GrdCredentials * grd_context_get_credentials (GrdContext *context);
+
 GrdEglThread * grd_context_get_egl_thread (GrdContext *context);
 
 GrdDebugFlags grd_context_get_debug_flags (GrdContext *context);
diff --git a/src/grd-credentials-libsecret.c b/src/grd-credentials-libsecret.c
new file mode 100644
index 00000000..72530cba
--- /dev/null
+++ b/src/grd-credentials-libsecret.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2018-2022 Red Hat Inc.
+ * Copyright (C) 2020 Pascal Nowack
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "grd-credentials-libsecret.h"
+
+#include <gio/gio.h>
+#include <libsecret/secret.h>
+#include <stdio.h>
+
+#define GRD_RDP_CREDENTIALS_SCHEMA (get_rdp_schema ())
+
+#define GRD_VNC_PASSWORD_SCHEMA (get_vnc_schema ())
+#define GRD_VNC_LEGACY_PASSWORD_SCHEMA (get_legacy_vnc_schema ())
+
+struct _GrdCredentialsLibsecret
+{
+  GrdCredentials parent;
+};
+
+G_DEFINE_TYPE (GrdCredentialsLibsecret,
+               grd_credentials_libsecret,
+               GRD_TYPE_CREDENTIALS)
+
+static const SecretSchema *
+get_rdp_schema (void)
+{
+  static const SecretSchema grd_rdp_credentials_schema = {
+    .name = "org.gnome.RemoteDesktop.RdpCredentials",
+    .flags = SECRET_SCHEMA_NONE,
+    .attributes = {
+      { "credentials", SECRET_SCHEMA_ATTRIBUTE_STRING },
+      { "NULL", 0 },
+    },
+  };
+
+  return &grd_rdp_credentials_schema;
+}
+
+static const SecretSchema *
+get_legacy_vnc_schema (void)
+{
+  static const SecretSchema grd_vnc_password_schema = {
+    .name = "org.gnome.RemoteDesktop.VncPassword",
+    .flags = SECRET_SCHEMA_NONE,
+    .attributes = {
+      { "password", SECRET_SCHEMA_ATTRIBUTE_STRING },
+      { "NULL", 0 },
+    },
+  };
+
+  return &grd_vnc_password_schema;
+}
+
+static const SecretSchema *
+get_vnc_schema (void)
+{
+  static const SecretSchema grd_vnc_password_schema = {
+    .name = "org.gnome.RemoteDesktop.VncCredentials",
+    .flags = SECRET_SCHEMA_NONE,
+    .attributes = {
+      { "password", SECRET_SCHEMA_ATTRIBUTE_STRING },
+      { "NULL", 0 },
+    },
+  };
+
+  return &grd_vnc_password_schema;
+}
+
+static const SecretSchema *
+schema_from_type (GrdCredentialsType type)
+{
+  switch (type)
+    {
+    case GRD_CREDENTIALS_TYPE_RDP:
+      return GRD_RDP_CREDENTIALS_SCHEMA;
+    case GRD_CREDENTIALS_TYPE_VNC:
+      return GRD_VNC_PASSWORD_SCHEMA;
+    }
+
+  g_assert_not_reached ();
+}
+
+static const char *
+description_from_type (GrdCredentialsType type)
+{
+  switch (type)
+    {
+    case GRD_CREDENTIALS_TYPE_RDP:
+      return "GNOME Remote Desktop RDP credentials";
+    case GRD_CREDENTIALS_TYPE_VNC:
+      return "GNOME Remote Desktop VNC password";
+    }
+
+  g_assert_not_reached ();
+}
+
+static gboolean
+grd_credentials_libsecret_store (GrdCredentials      *credentials,
+                                 GrdCredentialsType   type,
+                                 GVariant            *variant,
+                                 GError             **error)
+{
+  g_autofree char *serialized = NULL;
+
+  g_variant_ref_sink (variant);
+  serialized = g_variant_print (variant, TRUE);
+  g_variant_unref (variant);
+
+  return secret_password_store_sync (schema_from_type (type),
+                                     SECRET_COLLECTION_DEFAULT,
+                                     description_from_type (type),
+                                     serialized,
+                                     NULL, error,
+                                     NULL);
+}
+
+static GVariant *
+grd_credentials_libsecret_lookup (GrdCredentials      *credentials,
+                                  GrdCredentialsType   type,
+                                  GError             **error)
+{
+  g_autofree char *serialized = NULL;
+
+  serialized = secret_password_lookup_sync (schema_from_type (type),
+                                            NULL, error,
+                                            NULL);
+  if (!serialized)
+    return NULL;
+
+  return g_variant_parse (NULL, serialized, NULL, NULL, error);
+}
+
+static gboolean
+grd_credentials_libsecret_clear (GrdCredentials      *credentials,
+                                 GrdCredentialsType   type,
+                                 GError             **error)
+{
+  return secret_password_clear_sync (schema_from_type (type),
+                                     NULL, error,
+                                     NULL);
+}
+
+GrdCredentialsLibsecret *
+grd_credentials_libsecret_new (void)
+{
+  return g_object_new (GRD_TYPE_CREDENTIALS_LIBSECRET, NULL);
+}
+
+static void
+grd_credentials_libsecret_init (GrdCredentialsLibsecret *credentials_libsecret)
+{
+}
+
+static void
+maybe_migrate_legacy_vnc_password (GrdCredentials *credentials)
+{
+  g_autoptr (GError) error = NULL;
+  g_autofree char *password = NULL;
+
+  password = secret_password_lookup_sync (GRD_VNC_LEGACY_PASSWORD_SCHEMA,
+                                          NULL, &error,
+                                          NULL);
+  if (!password)
+    {
+      if (error)
+        {
+          g_printerr ("Failed to lookup legacy VNC password schema: %s\n",
+                      error->message);
+        }
+    }
+  else
+    {
+      g_printerr ("Migrating VNC password to new schema... ");
+
+      if (!grd_credentials_store (credentials,
+                                  GRD_CREDENTIALS_TYPE_VNC,
+                                  g_variant_new_string (password),
+                                  &error))
+        {
+          g_printerr ("Failed to migrate VNC password to new schema: %s\n",
+                      error->message);
+        }
+      else
+        {
+          if (!secret_password_clear_sync (GRD_VNC_LEGACY_PASSWORD_SCHEMA,
+                                           NULL, &error, NULL))
+            {
+              g_printerr ("Failed to clear VNC password from old schema: %s\n",
+                          error->message);
+            }
+          else
+            {
+              g_printerr ("OK\n");
+            }
+        }
+    }
+}
+
+static void
+grd_credentials_libsecret_constructed (GObject *object)
+{
+  GrdCredentials *credentials = GRD_CREDENTIALS (object);
+
+  maybe_migrate_legacy_vnc_password (credentials);
+
+  G_OBJECT_CLASS (grd_credentials_libsecret_parent_class)->constructed (object);
+}
+
+static void
+grd_credentials_libsecret_class_init (GrdCredentialsLibsecretClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GrdCredentialsClass *credentials_class = GRD_CREDENTIALS_CLASS (klass);
+
+  object_class->constructed = grd_credentials_libsecret_constructed;
+
+  credentials_class->store = grd_credentials_libsecret_store;
+  credentials_class->lookup = grd_credentials_libsecret_lookup;
+  credentials_class->clear = grd_credentials_libsecret_clear;
+}
diff --git a/src/grd-schemas.h b/src/grd-credentials-libsecret.h
similarity index 65%
rename from src/grd-schemas.h
rename to src/grd-credentials-libsecret.h
index 413a247c..00edaf5a 100644
--- a/src/grd-schemas.h
+++ b/src/grd-credentials-libsecret.h
@@ -19,17 +19,15 @@
  *
  */
 
-#ifndef GRD_SCHEMAS_H
-#define GRD_SCHEMAS_H
+#ifndef GRD_CREDENTIALS_LIBSECRET_H
+#define GRD_CREDENTIALS_LIBSECRET_H
 
-#include <libsecret/secret.h>
+#include "grd-credentials.h"
 
-const SecretSchema * grd_rdp_credentials_get_schema (void);
+#define GRD_TYPE_CREDENTIALS_LIBSECRET (grd_credentials_libsecret_get_type ())
+G_DECLARE_FINAL_TYPE (GrdCredentialsLibsecret, grd_credentials_libsecret,
+                      GRD, CREDENTIALS_LIBSECRET, GrdCredentials)
 
-const SecretSchema * grd_vnc_password_get_schema (void);
+GrdCredentialsLibsecret * grd_credentials_libsecret_new (void);
 
-#define GRD_RDP_CREDENTIALS_SCHEMA (grd_rdp_credentials_get_schema ())
-
-#define GRD_VNC_PASSWORD_SCHEMA (grd_vnc_password_get_schema ())
-
-#endif /* GRD_SCHEMA_H */
+#endif /* GRD_CREDENTIALS_LIBSECRET_H */
diff --git a/src/grd-credentials.c b/src/grd-credentials.c
new file mode 100644
index 00000000..b1ccddbb
--- /dev/null
+++ b/src/grd-credentials.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "grd-credentials.h"
+
+G_DEFINE_ABSTRACT_TYPE (GrdCredentials, grd_credentials, G_TYPE_OBJECT)
+
+GVariant *
+grd_credentials_lookup (GrdCredentials      *credentials,
+                        GrdCredentialsType   type,
+                        GError             **error)
+{
+  return GRD_CREDENTIALS_GET_CLASS (credentials)->lookup (credentials,
+                                                          type, error);
+}
+
+gboolean
+grd_credentials_clear (GrdCredentials      *credentials,
+                       GrdCredentialsType   type,
+                       GError             **error)
+{
+  return GRD_CREDENTIALS_GET_CLASS (credentials)->clear (credentials,
+                                                         type, error);
+}
+
+gboolean
+grd_credentials_store (GrdCredentials      *credentials,
+                       GrdCredentialsType   type,
+                       GVariant            *variant,
+                       GError             **error)
+{
+  return GRD_CREDENTIALS_GET_CLASS (credentials)->store (credentials,
+                                                         type, variant, error);
+}
+
+static void
+grd_credentials_init (GrdCredentials *credentials)
+{
+}
+
+static void
+grd_credentials_class_init (GrdCredentialsClass *klass)
+{
+}
diff --git a/src/grd-credentials.h b/src/grd-credentials.h
new file mode 100644
index 00000000..ad6c8788
--- /dev/null
+++ b/src/grd-credentials.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ */
+
+#ifndef GRD_CREDENTIALS_H
+#define GRD_CREDENTIALS_H
+
+#include <glib-object.h>
+
+typedef enum _GrdCredentialsType
+{
+  GRD_CREDENTIALS_TYPE_RDP,
+  GRD_CREDENTIALS_TYPE_VNC,
+} GrdCredentialsType;
+
+#define GRD_TYPE_CREDENTIALS (grd_credentials_get_type ())
+G_DECLARE_DERIVABLE_TYPE (GrdCredentials, grd_credentials,
+                          GRD, CREDENTIALS, GObject)
+
+struct _GrdCredentialsClass
+{
+  GObjectClass parent_class;
+
+  gboolean (* store) (GrdCredentials      *credentials,
+                      GrdCredentialsType   type,
+                      GVariant            *variant,
+                      GError             **error);
+
+  GVariant * (* lookup) (GrdCredentials      *credentials,
+                         GrdCredentialsType   type,
+                         GError             **error);
+
+  gboolean (* clear) (GrdCredentials      *credentials,
+                      GrdCredentialsType   type,
+                      GError             **error);
+};
+
+gboolean grd_credentials_store (GrdCredentials      *credentials,
+                                GrdCredentialsType   type,
+                                GVariant            *variant,
+                                GError             **error);
+
+GVariant * grd_credentials_lookup (GrdCredentials      *credentials,
+                                   GrdCredentialsType   type,
+                                   GError             **error);
+
+gboolean grd_credentials_clear (GrdCredentials      *credentials,
+                                GrdCredentialsType   type,
+                                GError             **error);
+
+#endif /* GRD_CREDENTIALS_H */
diff --git a/src/grd-ctl.c b/src/grd-ctl.c
index ddf44df5..f13a5fab 100644
--- a/src/grd-ctl.c
+++ b/src/grd-ctl.c
@@ -20,11 +20,11 @@
 
 #include "config.h"
 
+#include <gio/gio.h>
 #include <glib/gi18n.h>
-#include <libsecret/secret.h>
 #include <stdio.h>
 
-#include "grd-schemas.h"
+#include "grd-credentials-libsecret.h"
 
 #define GRD_RDP_SETTINGS_SCHEMA "org.gnome.desktop.remote-desktop.rdp"
 #define GRD_VNC_SETTINGS_SCHEMA "org.gnome.desktop.remote-desktop.vnc"
@@ -87,39 +87,41 @@ process_options (int                argc,
   return EXIT_FAILURE;
 }
 
+static GrdCredentials *
+create_credentials (void)
+{
+  return GRD_CREDENTIALS (grd_credentials_libsecret_new ());
+}
+
 #ifdef HAVE_RDP
 static gboolean
 grd_store_rdp_credentials (const char  *username,
                            const char  *password,
                            GError     **error)
 {
+  g_autoptr (GrdCredentials) credentials = NULL;
   GVariantBuilder builder;
-  g_autofree char *credentials = NULL;
 
   g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
   g_variant_builder_add (&builder, "{sv}",
                          "username", g_variant_new_string (username));
   g_variant_builder_add (&builder, "{sv}",
                          "password", g_variant_new_string (password));
-  credentials = g_variant_print (g_variant_builder_end (&builder), TRUE);
 
-  if (!secret_password_store_sync (GRD_RDP_CREDENTIALS_SCHEMA,
-                                   SECRET_COLLECTION_DEFAULT,
-                                   "GNOME Remote Desktop RDP credentials",
-                                   credentials,
-                                   NULL, error,
-                                   NULL))
-    return FALSE;
-
-  return TRUE;
+  credentials = create_credentials ();
+  return grd_credentials_store (credentials,
+                                GRD_CREDENTIALS_TYPE_RDP,
+                                g_variant_builder_end (&builder),
+                                error);
 }
 
 static gboolean
 grd_clear_rdp_credentials (GError **error)
 {
-  return secret_password_clear_sync (GRD_RDP_CREDENTIALS_SCHEMA,
-                                     NULL, error,
-                                     NULL);
+  g_autoptr (GrdCredentials) credentials = NULL;
+
+  credentials = create_credentials ();
+  return grd_credentials_clear (credentials, GRD_CREDENTIALS_TYPE_RDP, error);
 }
 
 static gboolean
@@ -279,6 +281,7 @@ vnc_set_credentials (int      argc,
                      char   **argv,
                      GError **error)
 {
+  g_autoptr (GrdCredentials) credentials = NULL;
   char *password;
 
   password = argv[0];
@@ -289,15 +292,11 @@ vnc_set_credentials (int      argc,
       return FALSE;
     }
 
-  if (!secret_password_store_sync (GRD_VNC_PASSWORD_SCHEMA,
-                                   SECRET_COLLECTION_DEFAULT,
-                                   "GNOME Remote Desktop VNC password",
-                                   password,
-                                   NULL, error,
-                                   NULL))
-    return FALSE;
-
-  return TRUE;
+  credentials = create_credentials ();
+  return grd_credentials_store (credentials,
+                                GRD_CREDENTIALS_TYPE_VNC,
+                                g_variant_new_string (password),
+                                error);
 }
 
 static gboolean
@@ -305,9 +304,10 @@ vnc_clear_credentials (int      argc,
                        char   **argv,
                        GError **error)
 {
-  return secret_password_clear_sync (GRD_VNC_PASSWORD_SCHEMA,
-                                     NULL, error,
-                                     NULL);
+  g_autoptr (GrdCredentials) credentials = NULL;
+
+  credentials = create_credentials ();
+  return grd_credentials_clear (credentials, GRD_CREDENTIALS_TYPE_VNC, error);
 }
 
 static gboolean
@@ -468,18 +468,19 @@ static void
 print_rdp_status (gboolean use_colors,
                   gboolean show_credentials)
 {
+  g_autoptr (GrdCredentials) credentials = NULL;
   g_autoptr (GSettings) rdp_settings = NULL;
   g_autofree char *tls_cert = NULL;
   g_autofree char *tls_key = NULL;
-  g_autofree char *credentials_string = NULL;
-  g_autoptr (GVariant) credentials = NULL;
+  g_autoptr (GVariant) rdp_credentials = NULL;
   g_autofree char *username = NULL;
   g_autofree char *password = NULL;
   g_autoptr (GError) error = NULL;
 
-  credentials_string = secret_password_lookup_sync (GRD_RDP_CREDENTIALS_SCHEMA,
-                                                    NULL, &error,
-                                                    NULL);
+  credentials = create_credentials ();
+  rdp_credentials = grd_credentials_lookup (credentials,
+                                            GRD_CREDENTIALS_TYPE_RDP,
+                                            &error);
   if (error)
     {
       fprintf (stderr, "Failed to lookup RDP credentials: %s", error->message);
@@ -500,12 +501,10 @@ print_rdp_status (gboolean use_colors,
   printf ("\tView-only: %s\n",
           g_settings_get_boolean (rdp_settings, "view-only") ? "yes" : "no");
 
-  if (credentials_string)
+  if (rdp_credentials)
     {
-      credentials = g_variant_parse (NULL, credentials_string,
-                                     NULL, NULL, NULL);
-      g_variant_lookup (credentials, "username", "s", &username);
-      g_variant_lookup (credentials, "password", "s", &password);
+      g_variant_lookup (rdp_credentials, "username", "s", &username);
+      g_variant_lookup (rdp_credentials, "password", "s", &password);
     }
 
   if (show_credentials)
@@ -528,20 +527,26 @@ static void
 print_vnc_status (gboolean use_colors,
                   gboolean show_credentials)
 {
+  g_autoptr (GrdCredentials) credentials = NULL;
   g_autoptr (GSettings) vnc_settings = NULL;
+  g_autoptr (GVariant) password_variant = NULL;
   g_autofree char *auth_method = NULL;
-  g_autofree char *password = NULL;
+  const char *password = NULL;
   g_autoptr (GError) error = NULL;
 
-  password = secret_password_lookup_sync (GRD_VNC_PASSWORD_SCHEMA,
-                                          NULL, &error,
-                                          NULL);
+  credentials = create_credentials ();
+  password_variant = grd_credentials_lookup (credentials,
+                                             GRD_CREDENTIALS_TYPE_VNC,
+                                             &error);
   if (error)
     {
       fprintf (stderr, "Failed to lookup RDP credentials: %s", error->message);
       return;
     }
 
+  if (password_variant)
+    password = g_variant_get_string (password_variant, NULL);
+
   vnc_settings = g_settings_new (GRD_VNC_SETTINGS_SCHEMA);
 
   printf ("VNC:\n");
diff --git a/src/grd-session-rdp.c b/src/grd-session-rdp.c
index 18c069ab..7f3667ba 100644
--- a/src/grd-session-rdp.c
+++ b/src/grd-session-rdp.c
@@ -2135,17 +2135,11 @@ grd_session_rdp_new (GrdRdpServer      *rdp_server,
 
   context = grd_rdp_server_get_context (rdp_server);
   settings = grd_context_get_settings (context);
-  username = grd_settings_get_rdp_username (settings, &error);
-  if (!username)
+  if (!grd_settings_get_rdp_credentials (settings,
+                                         &username, &password,
+                                         &error))
     {
-      g_warning ("Couldn't retrieve RDP username: %s", error->message);
-      return NULL;
-    }
-  password = grd_settings_get_rdp_password (settings, &error);
-  if (!password)
-    {
-      g_warning ("Couldn't retrieve RDP password: %s", error->message);
-      g_free (username);
+      g_warning ("Couldn't retrieve RDP credentials: %s", error->message);
       return NULL;
     }
 
diff --git a/src/grd-settings.c b/src/grd-settings.c
index f8f34021..fc004fdc 100644
--- a/src/grd-settings.c
+++ b/src/grd-settings.c
@@ -25,7 +25,8 @@
 #include <gio/gio.h>
 #include <string.h>
 
-#include "grd-schemas.h"
+#include "grd-context.h"
+#include "grd-credentials.h"
 
 #define GRD_RDP_SCHEMA_ID "org.gnome.desktop.remote-desktop.rdp"
 #define GRD_VNC_SCHEMA_ID "org.gnome.desktop.remote-desktop.vnc"
@@ -54,6 +55,8 @@ struct _GrdSettings
 {
   GObject parent;
 
+  GrdContext *context;
+
   struct {
     GSettings *settings;
 
@@ -126,112 +129,90 @@ grd_settings_get_rdp_server_key (GrdSettings *settings)
   return settings->rdp.server_key;
 }
 
-char *
-grd_settings_get_rdp_username (GrdSettings  *settings,
-                               GError      **error)
+gboolean
+grd_settings_get_rdp_credentials (GrdSettings  *settings,
+                                  char        **out_username,
+                                  char        **out_password,
+                                  GError      **error)
 {
+  GrdContext *context = settings->context;
   const char *test_username_override;
+  const char *test_password_override;
   g_autofree char *credentials_string = NULL;
   g_autoptr (GVariant) credentials = NULL;
-  char *username = NULL;
+  g_autofree char *username = NULL;
+  g_autofree char *password = NULL;
 
   test_username_override = g_getenv ("GNOME_REMOTE_DESKTOP_TEST_RDP_USERNAME");
-  if (test_username_override)
-    return g_strdup (test_username_override);
+  test_password_override = g_getenv ("GNOME_REMOTE_DESKTOP_TEST_RDP_PASSWORD");
 
-  credentials_string = secret_password_lookup_sync (GRD_RDP_CREDENTIALS_SCHEMA,
-                                                    NULL, error,
-                                                    NULL);
-  if (!credentials_string)
+  if (test_username_override && test_password_override)
     {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
-                   "Credentials not set");
-      return NULL;
+      *out_username = g_strdup (test_username_override);
+      *out_password = g_strdup (test_password_override);
+      return TRUE;
     }
 
-  credentials = g_variant_parse (NULL, credentials_string, NULL, NULL, NULL);
+  credentials = grd_credentials_lookup (grd_context_get_credentials (context),
+                                        GRD_CREDENTIALS_TYPE_RDP,
+                                        error);
   if (!credentials)
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
-                   "Unable to parse credentials");
-      return NULL;
-    }
+    return FALSE;
 
-  g_variant_lookup (credentials, "username", "s", &username);
-  if (!username)
+  if (!test_username_override)
     {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
-                   "Username not set");
-      return NULL;
+      g_variant_lookup (credentials, "username", "s", &username);
+      if (!username)
+        {
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+                       "Username not set");
+          return FALSE;
+        }
     }
-
-  return username;
-}
-
-char *
-grd_settings_get_rdp_password (GrdSettings  *settings,
-                               GError      **error)
-{
-  const char *test_password_override;
-  g_autofree char *credentials_string = NULL;
-  g_autoptr (GVariant) credentials = NULL;
-  char *password = NULL;
-
-  test_password_override = g_getenv ("GNOME_REMOTE_DESKTOP_TEST_RDP_PASSWORD");
-  if (test_password_override)
-    return g_strdup (test_password_override);
-
-  credentials_string = secret_password_lookup_sync (GRD_RDP_CREDENTIALS_SCHEMA,
-                                                    NULL, error,
-                                                    NULL);
-  if (!credentials_string)
+  else
     {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
-                   "Credentials not set");
-      return NULL;
+      username = g_strdup (test_username_override);
     }
 
-  credentials = g_variant_parse (NULL, credentials_string, NULL, NULL, NULL);
-  if (!credentials)
+  if (!test_password_override)
     {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
-                   "Unable to parse credentials");
-      return NULL;
+      g_variant_lookup (credentials, "password", "s", &password);
+      if (!password)
+        {
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+                       "Username not set");
+          return FALSE;
+        }
     }
-
-  g_variant_lookup (credentials, "password", "s", &password);
-  if (!password)
+  else
     {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
-                   "Password not set");
-      return NULL;
+      password = g_strdup (test_password_override);
     }
 
-  return password;
+  *out_username = g_steal_pointer (&username);
+  *out_password = g_steal_pointer (&password);
+  return TRUE;
 }
 
 char *
 grd_settings_get_vnc_password (GrdSettings  *settings,
                                GError      **error)
 {
+  GrdContext *context = settings->context;
   const char *test_password_override;
-  char *password;
+  g_autoptr (GVariant) password = NULL;
 
   test_password_override = g_getenv ("GNOME_REMOTE_DESKTOP_TEST_VNC_PASSWORD");
   if (test_password_override)
     return g_strdup (test_password_override);
 
-  password = secret_password_lookup_sync (GRD_VNC_PASSWORD_SCHEMA,
-                                          NULL, error,
-                                          NULL);
+  password = grd_credentials_lookup (grd_context_get_credentials (context),
+                                     GRD_CREDENTIALS_TYPE_VNC,
+                                     error);
   if (!password)
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
-                   "Password not set");
-      return NULL;
-    }
+    return NULL;
 
-  return password;
+  return g_variant_dup_string (password, NULL);
 }
 
 gboolean
@@ -391,6 +372,17 @@ on_vnc_settings_changed (GSettings   *vnc_settings,
     }
 }
 
+GrdSettings *
+grd_settings_new (GrdContext *context)
+{
+  GrdSettings *settings;
+
+  settings = g_object_new (GRD_TYPE_SETTINGS, NULL);
+  settings->context = context;
+
+  return settings;
+}
+
 static void
 grd_settings_finalize (GObject *object)
 {
diff --git a/src/grd-settings.h b/src/grd-settings.h
index a73e72de..a000fb21 100644
--- a/src/grd-settings.h
+++ b/src/grd-settings.h
@@ -22,14 +22,16 @@
 #define GRD_SETTINGS_H
 
 #include <glib-object.h>
-#include <libsecret/secret.h>
 
 #include "grd-enums.h"
+#include "grd-types.h"
 
 #define GRD_TYPE_SETTINGS (grd_settings_get_type ())
 G_DECLARE_FINAL_TYPE (GrdSettings, grd_settings,
                       GRD, SETTINGS, GObject)
 
+GrdSettings * grd_settings_new (GrdContext *context);
+
 gboolean grd_settings_is_rdp_enabled (GrdSettings *settings);
 
 gboolean grd_settings_is_vnc_enabled (GrdSettings *settings);
@@ -50,15 +52,14 @@ char * grd_settings_get_rdp_server_cert (GrdSettings *settings);
 
 char * grd_settings_get_rdp_server_key (GrdSettings *settings);
 
-char * grd_settings_get_rdp_password (GrdSettings  *settings,
-                                      GError      **error);
+gboolean grd_settings_get_rdp_credentials (GrdSettings  *settings,
+                                           char        **username,
+                                           char        **password,
+                                           GError      **error);
 
 char * grd_settings_get_vnc_password (GrdSettings  *settings,
                                       GError      **error);
 
-char * grd_settings_get_rdp_username (GrdSettings  *settings,
-                                      GError      **error);
-
 gboolean grd_settings_get_rdp_view_only (GrdSettings *settings);
 
 gboolean grd_settings_get_vnc_view_only (GrdSettings *settings);
diff --git a/src/grd-types.h b/src/grd-types.h
index 7b1767db..a8faa4f2 100644
--- a/src/grd-types.h
+++ b/src/grd-types.h
@@ -27,6 +27,7 @@ typedef struct _GrdClipboard GrdClipboard;
 typedef struct _GrdClipboardRdp GrdClipboardRdp;
 typedef struct _GrdClipboardVnc GrdClipboardVnc;
 typedef struct _GrdContext GrdContext;
+typedef struct _GrdCredentials GrdCredentials;
 typedef struct _GrdEglThread GrdEglThread;
 typedef struct _GrdHwAccelNvidia GrdHwAccelNvidia;
 typedef struct _GrdRdpBuffer GrdRdpBuffer;
diff --git a/src/meson.build b/src/meson.build
index 6c0bf845..31556d06 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -12,6 +12,13 @@ deps = [
   drm_dep,
 ]
 
+credentials_sources = files([
+  'grd-credentials.c',
+  'grd-credentials.h',
+  'grd-credentials-libsecret.c',
+  'grd-credentials-libsecret.h',
+])
+
 daemon_sources = files([
   'grd-clipboard.c',
   'grd-clipboard.h',
@@ -30,8 +37,6 @@ daemon_sources = files([
   'grd-private.h',
   'grd-prompt.c',
   'grd-prompt.h',
-  'grd-schemas.c',
-  'grd-schemas.h',
   'grd-session.c',
   'grd-session.h',
   'grd-settings.c',
@@ -123,6 +128,8 @@ if have_vnc
   ]
 endif
 
+daemon_sources += credentials_sources
+
 gen_daemon_sources = []
 
 gen_daemon_sources += gnome.gdbus_codegen('grd-dbus-screen-cast',
@@ -142,8 +149,7 @@ control_sources = ([
 
 ctl_sources = ([
   'grd-ctl.c',
-  'grd-schemas.c',
-  'grd-schemas.h',
+  credentials_sources,
 ])
 
 executable('gnome-remote-desktop-daemon',


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