summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ã…dahl <jadahl@gmail.com>2022-02-22 10:30:07 +0100
committerFelipe Borges <felipeborges@gnome.org>2022-02-26 18:19:14 +0000
commit3631338676d50ee13d839a03cdcb2333369cc0db (patch)
tree74325665ee912fceb8cc68a96b61d263d1bbb074
parent2f298c1cb2eee52cbb764b3c75c047f507a61739 (diff)
downloadgnome-control-center-3631338676d50ee13d839a03cdcb2333369cc0db.tar.gz
sharing: Generate RDP TLS certificates when missing
This also hooks up the certificate verification dialog to the configured TLS certificate.
-rw-r--r--meson.build1
-rw-r--r--panels/sharing/cc-sharing-panel.c214
-rw-r--r--panels/sharing/cc-sharing-panel.ui23
-rw-r--r--panels/sharing/meson.build1
-rw-r--r--panels/sharing/sharing.css4
-rw-r--r--panels/sharing/sharing.gresource.xml1
-rw-r--r--panels/wwan/meson.build4
7 files changed, 244 insertions, 4 deletions
diff --git a/meson.build b/meson.build
index d963651f9..73f2ba303 100644
--- a/meson.build
+++ b/meson.build
@@ -128,6 +128,7 @@ gudev_dep = dependency('gudev-1.0', version: '>= 232')
x11_dep = dependency('x11')
xi_dep = dependency('xi', version: '>= 1.2')
epoxy_dep = dependency('epoxy')
+gcr_dep = dependency('gcr-base-3')
m_dep = cc.find_library('m')
diff --git a/panels/sharing/cc-sharing-panel.c b/panels/sharing/cc-sharing-panel.c
index c2f998625..9c9fcafa2 100644
--- a/panels/sharing/cc-sharing-panel.c
+++ b/panels/sharing/cc-sharing-panel.c
@@ -29,12 +29,17 @@
#include "cc-media-sharing.h"
#include "cc-sharing-networks.h"
#include "cc-gnome-remote-desktop.h"
+#include "cc-tls-certificate.h"
#include "org.gnome.SettingsDaemon.Sharing.h"
#ifdef GDK_WINDOWING_WAYLAND
#include <gdk/wayland/gdkwayland.h>
#endif
#include <glib/gi18n.h>
+
+#define GCR_API_SUBJECT_TO_CHANGE
+#include <gcr/gcr-base.h>
+
#include <config.h>
static void cc_sharing_panel_setup_label_with_hostname (CcSharingPanel *self, GtkWidget *label);
@@ -82,7 +87,10 @@ struct _CcSharingPanel
GtkWidget *remote_desktop_address_label;
GtkWidget *remote_desktop_row;
GtkWidget *remote_desktop_switch;
+ GtkWidget *remote_desktop_verify_encryption;
GtkWidget *remote_desktop_fingerprint_dialog;
+ GtkWidget *remote_desktop_fingerprint_left;
+ GtkWidget *remote_desktop_fingerprint_right;
GtkWidget *shared_folders_grid;
GtkWidget *shared_folders_listbox;
@@ -91,6 +99,7 @@ struct _CcSharingPanel
guint remote_desktop_name_watch;
guint remote_desktop_store_credentials_id;
+ GTlsCertificate *remote_desktop_certificate;
};
CC_PANEL_REGISTER (CcSharingPanel, cc_sharing_panel)
@@ -173,6 +182,54 @@ cc_sharing_panel_get_help_uri (CcPanel *panel)
static void
remote_desktop_show_encryption_fingerprint (CcSharingPanel *self)
{
+ g_autoptr(GByteArray) der = NULL;
+ g_autoptr(GcrCertificate) gcr_cert = NULL;
+ g_autofree char *fingerprint = NULL;
+ g_auto(GStrv) fingerprintv = NULL;
+ g_autofree char *left_string = NULL;
+ g_autofree char *right_string = NULL;
+
+ g_return_if_fail (self->remote_desktop_certificate);
+
+ g_object_get (self->remote_desktop_certificate,
+ "certificate", &der, NULL);
+ gcr_cert = gcr_simple_certificate_new (der->data, der->len);
+ if (!gcr_cert)
+ {
+ g_warning ("Failed to load GCR TLS certificate representation");
+ return;
+ }
+
+ fingerprint = gcr_certificate_get_fingerprint_hex (gcr_cert, G_CHECKSUM_SHA256);
+
+ fingerprintv = g_strsplit (fingerprint, " ", -1);
+ g_return_if_fail (g_strv_length (fingerprintv) == 32);
+
+ left_string = g_strdup_printf (
+ "%s:%s:%s:%s\n"
+ "%s:%s:%s:%s\n"
+ "%s:%s:%s:%s\n"
+ "%s:%s:%s:%s\n",
+ fingerprintv[0], fingerprintv[1], fingerprintv[2], fingerprintv[3],
+ fingerprintv[8], fingerprintv[9], fingerprintv[10], fingerprintv[11],
+ fingerprintv[16], fingerprintv[17], fingerprintv[18], fingerprintv[19],
+ fingerprintv[24], fingerprintv[25], fingerprintv[26], fingerprintv[27]);
+
+ right_string = g_strdup_printf (
+ "%s:%s:%s:%s\n"
+ "%s:%s:%s:%s\n"
+ "%s:%s:%s:%s\n"
+ "%s:%s:%s:%s\n",
+ fingerprintv[4], fingerprintv[5], fingerprintv[6], fingerprintv[7],
+ fingerprintv[12], fingerprintv[13], fingerprintv[14], fingerprintv[15],
+ fingerprintv[20], fingerprintv[21], fingerprintv[22], fingerprintv[23],
+ fingerprintv[28], fingerprintv[29], fingerprintv[30], fingerprintv[31]);
+
+ gtk_label_set_label (GTK_LABEL (self->remote_desktop_fingerprint_left),
+ left_string);
+ gtk_label_set_label (GTK_LABEL (self->remote_desktop_fingerprint_right),
+ right_string);
+
gtk_window_set_transient_for (GTK_WINDOW (self->remote_desktop_fingerprint_dialog),
GTK_WINDOW (self->remote_desktop_dialog));
gtk_window_present (GTK_WINDOW (self->remote_desktop_fingerprint_dialog));
@@ -223,8 +280,11 @@ cc_sharing_panel_class_init (CcSharingPanelClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_password_entry);
gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_device_name_label);
gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_address_label);
+ gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_verify_encryption);
gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_fingerprint_dialog);
gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_row);
+ gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_fingerprint_left);
+ gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, remote_desktop_fingerprint_right);
gtk_widget_class_bind_template_child (widget_class, CcSharingPanel, shared_folders_listbox);
gtk_widget_class_bind_template_callback (widget_class, remote_desktop_show_encryption_fingerprint);
@@ -1049,12 +1109,155 @@ disable_gnome_remote_desktop_service (CcSharingPanel *self)
}
static void
+calc_default_tls_paths (char **out_dir_path,
+ char **out_cert_path,
+ char **out_key_path)
+{
+ g_autofree char *dir_path = NULL;
+
+ dir_path = g_strdup_printf ("%s/gnome-remote-desktop",
+ g_get_user_data_dir ());
+
+ if (out_cert_path)
+ *out_cert_path = g_strdup_printf ("%s/rdp-tls.crt", dir_path);
+ if (out_key_path)
+ *out_key_path = g_strdup_printf ("%s/rdp-tls.key", dir_path);
+
+ if (out_dir_path)
+ *out_dir_path = g_steal_pointer (&dir_path);
+}
+
+static void
+set_tls_certificate (CcSharingPanel *self,
+ GTlsCertificate *tls_certificate)
+{
+ g_set_object (&self->remote_desktop_certificate,
+ tls_certificate);
+ gtk_widget_set_sensitive (self->remote_desktop_verify_encryption, TRUE);
+}
+
+static void
+on_certificate_generated (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ CcSharingPanel *self;
+ g_autoptr(GTlsCertificate) tls_certificate = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autofree char *cert_path = NULL;
+ g_autofree char *key_path = NULL;
+ g_autoptr(GSettings) rdp_settings = NULL;
+
+ tls_certificate = bonsai_tls_certificate_new_generate_finish (res, &error);
+ if (!tls_certificate)
+ {
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ g_warning ("Failed to generate TLS certificate: %s", error->message);
+ return;
+ }
+
+ self = CC_SHARING_PANEL (user_data);
+
+ calc_default_tls_paths (NULL, &cert_path, &key_path);
+
+ rdp_settings = g_settings_new (GNOME_REMOTE_DESKTOP_RDP_SCHEMA_ID);
+
+ g_settings_set_string (rdp_settings, "tls-cert", cert_path);
+ g_settings_set_string (rdp_settings, "tls-key", key_path);
+
+ set_tls_certificate (self, tls_certificate);
+
+ enable_gnome_remote_desktop_service (self);
+}
+
+static void
+enable_gnome_remote_desktop (CcSharingPanel *self)
+{
+ g_autofree char *dir_path = NULL;
+ g_autofree char *cert_path = NULL;
+ g_autofree char *key_path = NULL;
+ g_autoptr(GFile) dir = NULL;
+ g_autoptr(GFile) cert_file = NULL;
+ g_autoptr(GFile) key_file = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GSettings) rdp_settings = NULL;
+
+ rdp_settings = g_settings_new (GNOME_REMOTE_DESKTOP_RDP_SCHEMA_ID);
+ cert_path = g_settings_get_string (rdp_settings, "tls-cert");
+ key_path = g_settings_get_string (rdp_settings, "tls-key");
+ if (strlen (cert_path) > 0 &&
+ strlen (key_path) > 0)
+ {
+ g_autoptr(GTlsCertificate) tls_certificate = NULL;
+
+ tls_certificate = g_tls_certificate_new_from_file (cert_path, &error);
+ if (tls_certificate)
+ {
+ set_tls_certificate (self, tls_certificate);
+
+ enable_gnome_remote_desktop_service (self);
+ return;
+ }
+
+ g_warning ("Configured TLS certificate invalid: %s", error->message);
+ return;
+ }
+
+ calc_default_tls_paths (&dir_path, &cert_path, &key_path);
+
+ dir = g_file_new_for_path (dir_path);
+ if (!g_file_query_exists (dir, NULL))
+ {
+ if (!g_file_make_directory_with_parents (dir, NULL, &error))
+ {
+ g_warning ("Failed to create remote desktop certificate directory: %s",
+ error->message);
+ return;
+ }
+ }
+
+ cert_file = g_file_new_for_path (cert_path);
+ key_file = g_file_new_for_path (key_path);
+
+ if (g_file_query_exists (cert_file, NULL) &&
+ g_file_query_exists (key_file, NULL))
+ {
+ g_autoptr(GTlsCertificate) tls_certificate = NULL;
+
+ tls_certificate = g_tls_certificate_new_from_file (cert_path, &error);
+ if (tls_certificate)
+ {
+ g_settings_set_string (rdp_settings, "tls-cert", cert_path);
+ g_settings_set_string (rdp_settings, "tls-key", key_path);
+
+ set_tls_certificate (self, tls_certificate);
+
+ enable_gnome_remote_desktop_service (self);
+ return;
+ }
+
+ g_warning ("Existing TLS certificate invalid: %s", error->message);
+ return;
+ }
+
+ bonsai_tls_certificate_new_generate_async (cert_path,
+ key_path,
+ "US",
+ "GNOME",
+ cc_panel_get_cancellable (CC_PANEL (self)),
+ on_certificate_generated,
+ self);
+}
+
+static void
on_remote_desktop_state_changed (GtkWidget *widget,
GParamSpec *pspec,
CcSharingPanel *self)
{
if (gtk_switch_get_active (GTK_SWITCH (widget)))
- enable_gnome_remote_desktop_service (self);
+ enable_gnome_remote_desktop (self);
else
disable_gnome_remote_desktop_service (self);
}
@@ -1253,6 +1456,8 @@ sharing_proxy_ready (GObject *source,
static void
cc_sharing_panel_init (CcSharingPanel *self)
{
+ g_autoptr(GtkCssProvider) provider = NULL;
+
g_resources_register (cc_sharing_get_resource ());
gtk_widget_init_template (GTK_WIDGET (self));
@@ -1289,6 +1494,13 @@ cc_sharing_panel_init (CcSharingPanel *self)
/* make sure the hostname entry isn't focused by default */
g_signal_connect_swapped (self, "map", G_CALLBACK (gtk_widget_grab_focus),
self->main_list_box);
+
+ provider = gtk_css_provider_new ();
+ gtk_css_provider_load_from_resource (provider,
+ "/org/gnome/control-center/sharing/sharing.css");
+ gtk_style_context_add_provider_for_display (gdk_display_get_default (),
+ GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
CcSharingPanel *
diff --git a/panels/sharing/cc-sharing-panel.ui b/panels/sharing/cc-sharing-panel.ui
index 04fcc6b5d..093cf5635 100644
--- a/panels/sharing/cc-sharing-panel.ui
+++ b/panels/sharing/cc-sharing-panel.ui
@@ -379,6 +379,29 @@
<object class="AdwStatusPage">
<property name="title" translatable="yes">Encryption Fingerprint</property>
<property name="description" translatable="yes">The encryption fingerprint can be seen in connecting clients and should be identical</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="halign">center</property>
+ <style>
+ <class name="tls-cert-verification" />
+ </style>
+ <child>
+ <object class="GtkLabel" id="remote_desktop_fingerprint_left">
+ <style>
+ <class name="tls-cert-fingerprint" />
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="remote_desktop_fingerprint_right">
+ <style>
+ <class name="tls-cert-fingerprint" />
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
</object>
</child>
</object>
diff --git a/panels/sharing/meson.build b/panels/sharing/meson.build
index 5d2bcba6e..1e72f935e 100644
--- a/panels/sharing/meson.build
+++ b/panels/sharing/meson.build
@@ -84,6 +84,7 @@ panels_libs += static_library(
common_deps,
libsecret_dep,
gnutls_dep,
+ gcr_dep,
],
c_args: cflags
)
diff --git a/panels/sharing/sharing.css b/panels/sharing/sharing.css
new file mode 100644
index 000000000..cf18ab392
--- /dev/null
+++ b/panels/sharing/sharing.css
@@ -0,0 +1,4 @@
+.tls-cert-fingerprint {
+ font-family: monospace;
+ margin: 10px;
+}
diff --git a/panels/sharing/sharing.gresource.xml b/panels/sharing/sharing.gresource.xml
index 75c7f7458..275f8846e 100644
--- a/panels/sharing/sharing.gresource.xml
+++ b/panels/sharing/sharing.gresource.xml
@@ -3,5 +3,6 @@
<gresource prefix="/org/gnome/control-center/sharing">
<file preprocess="xml-stripblanks">cc-sharing-panel.ui</file>
<file preprocess="xml-stripblanks">cc-sharing-networks.ui</file>
+ <file>sharing.css</file>
</gresource>
</gresources>
diff --git a/panels/wwan/meson.build b/panels/wwan/meson.build
index 04a092050..9b73b5bb1 100644
--- a/panels/wwan/meson.build
+++ b/panels/wwan/meson.build
@@ -1,7 +1,5 @@
-gcr_dep = [dependency('gcr-base-3')]
-
-deps = common_deps + network_manager_deps + gcr_dep + [polkit_gobject_dep]
+deps = common_deps + network_manager_deps + [gcr_dep, polkit_gobject_dep]
panels_list += cappletname
desktop = 'gnome-@0@-panel.desktop'.format(cappletname)