[gnome-remote-desktop] Add TPM credentials using headless runtime mode



commit 87569f6f3c39f1a3a3665013b4f8bbc99dec0343
Author: Jonas Ådahl <jadahl gmail com>
Date:   Tue Jun 21 18:56:42 2022 +0200

    Add TPM credentials using headless runtime mode
    
    Passing --headless to the daemon executable will cause
    gnome-remote-desktop to use the TPM 2.0 based credentials storage,
    meaning it can run without an active user session with an unlocked
    keyring.
    
    This mode doesn't yet do anything more, e.g. forcing using virtual
    monitors; that will come later.

 src/grd-context.c         | 33 ++++++++++++++++---
 src/grd-context.h         |  9 ++++++
 src/grd-credentials-tpm.c |  9 ++++++
 src/grd-daemon.c          | 81 ++++++++++++++++++++++++++++++++---------------
 4 files changed, 103 insertions(+), 29 deletions(-)
---
diff --git a/src/grd-context.c b/src/grd-context.c
index 7f45988e..f89ef93f 100644
--- a/src/grd-context.c
+++ b/src/grd-context.c
@@ -25,6 +25,7 @@
 #include "grd-context.h"
 
 #include "grd-credentials-libsecret.h"
+#include "grd-credentials-tpm.h"
 #include "grd-egl-thread.h"
 #include "grd-settings.h"
 
@@ -132,6 +133,34 @@ init_debug_flags (GrdContext *context)
     }
 }
 
+GrdContext *
+grd_context_new (GrdRuntimeMode   runtime_mode,
+                 GError         **error)
+{
+  g_autoptr (GrdContext) context = NULL;
+
+  context = g_object_new (GRD_TYPE_CONTEXT, NULL);
+
+  init_debug_flags (context);
+
+  switch (runtime_mode)
+    {
+    case GRD_RUNTIME_MODE_HEADLESS:
+      context->credentials = GRD_CREDENTIALS (grd_credentials_tpm_new (error));
+      break;
+    case GRD_RUNTIME_MODE_SCREEN_SHARE:
+      context->credentials = GRD_CREDENTIALS (grd_credentials_libsecret_new ());
+      break;
+    }
+
+  if (!context->credentials)
+    return NULL;
+
+  context->settings = grd_settings_new (context);
+
+  return g_steal_pointer (&context);
+}
+
 static void
 grd_context_finalize (GObject *object)
 {
@@ -149,10 +178,6 @@ grd_context_finalize (GObject *object)
 static void
 grd_context_init (GrdContext *context)
 {
-  init_debug_flags (context);
-
-  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 2efc4cdb..1ac87295 100644
--- a/src/grd-context.h
+++ b/src/grd-context.h
@@ -30,6 +30,12 @@
 #include "grd-settings.h"
 #include "grd-types.h"
 
+typedef enum _GrdRuntimeMode
+{
+  GRD_RUNTIME_MODE_SCREEN_SHARE,
+  GRD_RUNTIME_MODE_HEADLESS,
+} GrdRuntimeMode;
+
 typedef enum _GrdDebugFlags
 {
   GRD_DEBUG_NONE = 0,
@@ -39,6 +45,9 @@ typedef enum _GrdDebugFlags
 #define GRD_TYPE_CONTEXT (grd_context_get_type ())
 G_DECLARE_FINAL_TYPE (GrdContext, grd_context, GRD, CONTEXT, GObject)
 
+GrdContext * grd_context_new (GrdRuntimeMode   runtime_mode,
+                              GError         **error);
+
 GrdDBusRemoteDesktop * grd_context_get_remote_desktop_proxy (GrdContext *context);
 
 GrdDBusScreenCast * grd_context_get_screen_cast_proxy (GrdContext *context);
diff --git a/src/grd-credentials-tpm.c b/src/grd-credentials-tpm.c
index 86bc055c..3a0185b3 100644
--- a/src/grd-credentials-tpm.c
+++ b/src/grd-credentials-tpm.c
@@ -215,6 +215,15 @@ grd_credentials_tpm_clear (GrdCredentials      *credentials,
 GrdCredentialsTpm *
 grd_credentials_tpm_new (GError **error)
 {
+  g_autoptr (GrdTpm) tpm = NULL;
+
+  tpm = grd_tpm_new (GRD_TPM_MODE_NONE, error);
+  if (!tpm)
+    return NULL;
+
+  if (!grd_tpm_check_capabilities (tpm, error))
+    return NULL;
+
   return g_object_new (GRD_TYPE_CREDENTIALS_TPM, NULL);
 }
 
diff --git a/src/grd-daemon.c b/src/grd-daemon.c
index 78cbb0e5..29da104d 100644
--- a/src/grd-daemon.c
+++ b/src/grd-daemon.c
@@ -310,22 +310,6 @@ on_vnc_enabled_changed (GrdSettings *settings,
 static void
 grd_daemon_init (GrdDaemon *daemon)
 {
-  GrdSettings *settings;
-
-  daemon->context = g_object_new (GRD_TYPE_CONTEXT, NULL);
-
-  settings = grd_context_get_settings (daemon->context);
-
-#ifdef HAVE_RDP
-  g_signal_connect (settings, "rdp-enabled-changed",
-                    G_CALLBACK (on_rdp_enabled_changed),
-                    daemon);
-#endif
-#ifdef HAVE_VNC
-  g_signal_connect (settings, "vnc-enabled-changed",
-                    G_CALLBACK (on_vnc_enabled_changed),
-                    daemon);
-#endif
 }
 
 static void
@@ -456,17 +440,55 @@ register_signals (GrdDaemon *daemon)
   g_source_attach (daemon->sigterm_source, NULL);
 }
 
+static GrdDaemon *
+grd_daemon_new (GrdRuntimeMode   runtime_mode,
+                GError         **error)
+{
+  GrdContext *context;
+  GrdDaemon *daemon;
+  GrdSettings *settings;
+
+  context = grd_context_new (runtime_mode, error);
+  if (!context)
+    return NULL;
+
+  daemon = g_object_new (GRD_TYPE_DAEMON,
+                         "application-id", GRD_DAEMON_APPLICATION_ID,
+                         "flags", G_APPLICATION_IS_SERVICE,
+                         NULL);
+
+  daemon->context = context;
+
+  settings = grd_context_get_settings (daemon->context);
+
+#ifdef HAVE_RDP
+  g_signal_connect (settings, "rdp-enabled-changed",
+                    G_CALLBACK (on_rdp_enabled_changed),
+                    daemon);
+#endif
+#ifdef HAVE_VNC
+  g_signal_connect (settings, "vnc-enabled-changed",
+                    G_CALLBACK (on_vnc_enabled_changed),
+                    daemon);
+#endif
+
+  return daemon;
+}
+
 int
 main (int argc, char **argv)
 {
   GrdSettings *settings;
   gboolean print_version = FALSE;
+  gboolean headless = FALSE;
   int rdp_port = -1;
   int vnc_port = -1;
 
   GOptionEntry entries[] = {
     { "version", 0, 0, G_OPTION_ARG_NONE, &print_version,
       "Print version", NULL },
+    { "headless", 0, 0, G_OPTION_ARG_NONE, &headless,
+      "Run in headless mode", NULL },
     { "rdp-port", 0, 0, G_OPTION_ARG_INT, &rdp_port,
       "RDP port", NULL },
     { "vnc-port", 0, 0, G_OPTION_ARG_INT, &vnc_port,
@@ -474,8 +496,9 @@ main (int argc, char **argv)
     { NULL }
   };
   g_autoptr(GOptionContext) context = NULL;
-  g_autoptr(GApplication) app = NULL;
+  g_autoptr (GrdDaemon) daemon = NULL;
   GError *error = NULL;
+  GrdRuntimeMode runtime_mode;
 
   g_set_application_name (_("GNOME Remote Desktop"));
 
@@ -494,19 +517,27 @@ main (int argc, char **argv)
       return EXIT_SUCCESS;
     }
 
-  app = g_object_new (GRD_TYPE_DAEMON,
-                      "application-id", GRD_DAEMON_APPLICATION_ID,
-                      "flags", G_APPLICATION_IS_SERVICE,
-                      NULL);
+  if (headless)
+    runtime_mode = GRD_RUNTIME_MODE_HEADLESS;
+  else
+    runtime_mode = GRD_RUNTIME_MODE_SCREEN_SHARE;
 
-  add_actions (app);
-  register_signals (GRD_DAEMON (app));
+  daemon = grd_daemon_new (runtime_mode, &error);
+  if (!daemon)
+    {
+      g_printerr ("Failed to initialize: %s\n", error->message);
+      g_error_free (error);
+      return EXIT_FAILURE;
+    }
 
-  settings = grd_context_get_settings (GRD_DAEMON (app)->context);
+  add_actions (G_APPLICATION (daemon));
+  register_signals (daemon);
+
+  settings = grd_context_get_settings (daemon->context);
   if (rdp_port != -1)
     grd_settings_override_rdp_port (settings, rdp_port);
   if (vnc_port != -1)
     grd_settings_override_vnc_port (settings, vnc_port);
 
-  return g_application_run (app, argc, argv);
+  return g_application_run (G_APPLICATION (daemon), argc, argv);
 }


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