From aeae04453400765839e64192241a576366842661 Mon Sep 17 00:00:00 2001 From: Evangelos Ribeiro Tzaras Date: Mon, 9 May 2022 17:47:08 +0200 Subject: [PATCH] sip: account-widget: Add media encryption option This option can only be set when the transport protocol is set to TLS or the "always-allow-sdes" gsetting is used. --- plugins/sip/calls-sip-account-widget.c | 124 ++++++++++++++++++++++--- plugins/sip/sip-account-widget.ui | 7 ++ 2 files changed, 116 insertions(+), 15 deletions(-) diff --git a/plugins/sip/calls-sip-account-widget.c b/plugins/sip/calls-sip-account-widget.c index f774dda..499be6e 100644 --- a/plugins/sip/calls-sip-account-widget.c +++ b/plugins/sip/calls-sip-account-widget.c @@ -24,9 +24,13 @@ #define G_LOG_DOMAIN "CallsSipAccountWidget" +#include "calls-settings.h" #include "calls-sip-account-widget.h" #include "calls-sip-provider.h" #include "calls-sip-origin.h" +#include "calls-sip-util.h" + +#include /** * Section:calls-sip-account-widget @@ -67,6 +71,8 @@ struct _CallsSipAccountWidget { char *last_port; HdyComboRow *protocol; GListStore *protocols_store; /* bound model for protocol HdyComboRow */ + HdyComboRow *media_encryption; + GListStore *media_encryption_store; GtkSwitch *tel_switch; GtkSwitch *auto_connect_switch; @@ -76,6 +82,7 @@ struct _CallsSipAccountWidget { CallsSipOrigin *origin; /* nullable to add a new account */ /* misc */ + CallsSettings *settings; gboolean connecting; gboolean port_self_change; }; @@ -104,6 +111,39 @@ is_form_filled (CallsSipAccountWidget *self) g_strcmp0 (gtk_entry_get_text (self->port), "") != 0; } +static const char * +get_selected_protocol (CallsSipAccountWidget *self) +{ + g_autoptr (HdyValueObject) obj = NULL; + const char *protocol = NULL; + gint i; + + if ((i = hdy_combo_row_get_selected_index (self->protocol)) != -1) { + obj = g_list_model_get_item (G_LIST_MODEL (self->protocols_store), i); + protocol = hdy_value_object_get_string (obj); + } + return protocol; +} + + +static void +update_media_encryption (CallsSipAccountWidget *self) +{ + gboolean transport_is_tls; + gboolean sdes_always_allowed; + + g_assert (CALLS_IS_SIP_ACCOUNT_WIDGET (self)); + + transport_is_tls = g_strcmp0 (get_selected_protocol (self), "TLS") == 0; + sdes_always_allowed = calls_settings_get_always_allow_sdes (self->settings); + + gtk_widget_set_sensitive (GTK_WIDGET (self->media_encryption), + transport_is_tls | sdes_always_allowed); + + if (!transport_is_tls && !sdes_always_allowed) + hdy_combo_row_set_selected_index (self->media_encryption, 0); +} + static void on_user_changed (CallsSipAccountWidget *self) @@ -117,6 +157,8 @@ on_user_changed (CallsSipAccountWidget *self) gtk_widget_set_sensitive (self->apply_btn, is_form_filled (self) && is_form_valid (self)); + + update_media_encryption (self); } @@ -292,6 +334,35 @@ find_protocol (CallsSipAccountWidget *self, } +static gboolean +find_media_encryption (CallsSipAccountWidget *self, + const SipMediaEncryption encryption, + guint *index) +{ + guint len; + + g_assert (CALLS_IS_SIP_ACCOUNT_WIDGET (self)); + + len = g_list_model_get_n_items (G_LIST_MODEL (self->media_encryption_store)); + + for (guint i = 0; i < len; i++) { + g_autoptr (HdyValueObject) obj = + g_list_model_get_item (G_LIST_MODEL (self->media_encryption_store), i); + SipMediaEncryption obj_enc = + (SipMediaEncryption) GPOINTER_TO_INT (g_object_get_data (G_OBJECT (obj), "value")); + + if (obj_enc == encryption) { + if (index) + *index = i; + return TRUE; + } + } + + g_warning ("Could not find encryption mode %d", encryption); + return FALSE; +} + + static void clear_form (CallsSipAccountWidget *self) { @@ -303,6 +374,8 @@ clear_form (CallsSipAccountWidget *self) gtk_entry_set_text (self->password, ""); gtk_entry_set_text (self->port, "0"); hdy_combo_row_set_selected_index (self->protocol, 0); + gtk_widget_set_sensitive (GTK_WIDGET (self->media_encryption), FALSE); + hdy_combo_row_set_selected_index (self->media_encryption, 0); gtk_switch_set_state (self->tel_switch, FALSE); gtk_switch_set_state (self->auto_connect_switch, TRUE); @@ -326,6 +399,8 @@ edit_form (CallsSipAccountWidget *self, g_autofree char *port_str = NULL; g_autofree char *protocol = NULL; gint port; + SipMediaEncryption encryption; + guint encryption_index; guint protocol_index; gboolean can_tel; gboolean auto_connect; @@ -348,6 +423,7 @@ edit_form (CallsSipAccountWidget *self, "password", &password, "port", &port, "transport-protocol", &protocol, + "media-encryption", &encryption, "can-tel", &can_tel, "auto-connect", &auto_connect, NULL); @@ -361,6 +437,9 @@ edit_form (CallsSipAccountWidget *self, if (!find_protocol (self, protocol, &protocol_index)) protocol_index = 0; + if (!find_media_encryption (self, encryption, &encryption_index)) + encryption_index = 0; + /* set UI elements */ gtk_entry_set_text (self->host, host); gtk_entry_set_text (self->display_name, display_name ?: ""); @@ -369,6 +448,7 @@ edit_form (CallsSipAccountWidget *self, set_password_visibility (self, FALSE); gtk_entry_set_text (self->port, port_str); hdy_combo_row_set_selected_index (self->protocol, protocol_index); + hdy_combo_row_set_selected_index (self->media_encryption, encryption_index); gtk_switch_set_state (self->tel_switch, can_tel); gtk_switch_set_state (self->auto_connect_switch, auto_connect); @@ -381,21 +461,6 @@ edit_form (CallsSipAccountWidget *self, } -static const char * -get_selected_protocol (CallsSipAccountWidget *self) -{ - g_autoptr (HdyValueObject) obj = NULL; - const char *protocol = NULL; - gint i; - - if ((i = hdy_combo_row_get_selected_index (self->protocol)) != -1) { - obj = g_list_model_get_item (G_LIST_MODEL (self->protocols_store), i); - protocol = hdy_value_object_get_string (obj); - } - return protocol; -} - - static void on_login_clicked (CallsSipAccountWidget *self) { @@ -504,6 +569,7 @@ calls_sip_account_widget_dispose (GObject *object) g_clear_pointer (&self->last_port, g_free); g_clear_object (&self->protocols_store); + g_clear_object (&self->media_encryption_store); G_OBJECT_CLASS (calls_sip_account_widget_parent_class)->dispose (object); } @@ -550,6 +616,7 @@ calls_sip_account_widget_class_init (CallsSipAccountWidgetClass *klass) gtk_widget_class_bind_template_child (widget_class, CallsSipAccountWidget, password); gtk_widget_class_bind_template_child (widget_class, CallsSipAccountWidget, port); gtk_widget_class_bind_template_child (widget_class, CallsSipAccountWidget, protocol); + gtk_widget_class_bind_template_child (widget_class, CallsSipAccountWidget, media_encryption); gtk_widget_class_bind_template_child (widget_class, CallsSipAccountWidget, tel_switch); gtk_widget_class_bind_template_child (widget_class, CallsSipAccountWidget, auto_connect_switch); @@ -568,8 +635,35 @@ calls_sip_account_widget_init (CallsSipAccountWidget *self) { HdyValueObject *obj; + self->settings = calls_settings_get_default (); + + g_signal_connect_swapped (self->settings, + "notify::always-allow-sdes", + G_CALLBACK (update_media_encryption), + self); + gtk_widget_init_template (GTK_WIDGET (self)); + self->media_encryption_store = g_list_store_new (HDY_TYPE_VALUE_OBJECT); + + obj = hdy_value_object_new_string (_("No encryption")); + g_object_set_data (G_OBJECT (obj), + "value", GINT_TO_POINTER (SIP_MEDIA_ENCRYPTION_NONE)); + g_list_store_insert (self->media_encryption_store, 0, obj); + g_clear_object (&obj); + + /* TODO Optional encryption */ + obj = hdy_value_object_new_string (_("Force encryption")); + g_object_set_data (G_OBJECT (obj), + "value", GINT_TO_POINTER (SIP_MEDIA_ENCRYPTION_FORCED)); + g_list_store_insert (self->media_encryption_store, 1, obj); + g_clear_object (&obj); + + hdy_combo_row_bind_name_model (self->media_encryption, + G_LIST_MODEL (self->media_encryption_store), + (HdyComboRowGetNameFunc) hdy_value_object_dup_string, + NULL, NULL); + self->protocols_store = g_list_store_new (HDY_TYPE_VALUE_OBJECT); obj = hdy_value_object_new_string ("UDP"); diff --git a/plugins/sip/sip-account-widget.ui b/plugins/sip/sip-account-widget.ui index b0d73d9..83af8aa 100644 --- a/plugins/sip/sip-account-widget.ui +++ b/plugins/sip/sip-account-widget.ui @@ -183,6 +183,13 @@ + + + True + Media Encryption + + +