summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-06-08 13:23:49 +0200
committerThomas Haller <thaller@redhat.com>2016-06-13 10:51:17 +0200
commit7a2b964d6ac3f8407fa82e832e7e1a7550ba2c02 (patch)
treeaf7f834efb45d98ddb1e97cefddd187d1ae1030a
parent84b5f20a73d1754013d130b590ca84b80017507b (diff)
downloadnetwork-manager-applet-th/vpn-service-info-bgo767197-1.tar.gz
c-e: support multiple "Add VPN connection" entires per service-typeth/vpn-service-info-bgo767197-1
For one given service-type, the UI shall be able to show multiple entires in the list for creating a new connection. This works by asking the plugin whether it supports multiple "add-details". And if so, create an entry for each add-detail. When adding a VPN connection, the editor creates a NMConnection with initializing vpn.service-type and setting the add-detail to a key according to the plugin's instruction. For example, nm-openvpn supports multiple "vpn.connection-type" such as "tls", "static-key", "password", "password-tls". With this change, it could generate an entry for each type in nm-c-e's connection-add list. To do that, it should announce add-details to be "tls", "static-key", "password", "password-tls", and the "add-detail-key" to be "connection-type". This functionality is not accessible via $ nm-connection-editor -c -t vpn:<SERVICE_TYPE>:<ADD_DETAIL>
-rw-r--r--src/connection-editor/ce-new-connection.ui6
-rw-r--r--src/connection-editor/connection-helpers.c106
-rw-r--r--src/connection-editor/page-vpn.c5
-rw-r--r--src/connection-editor/page-vpn.h5
4 files changed, 104 insertions, 18 deletions
diff --git a/src/connection-editor/ce-new-connection.ui b/src/connection-editor/ce-new-connection.ui
index c9dfa547..66e9ae86 100644
--- a/src/connection-editor/ce-new-connection.ui
+++ b/src/connection-editor/ce-new-connection.ui
@@ -16,6 +16,12 @@
<column type="GObject"/>
<!-- column-name vpn_service_type, COL_VPN_SERVICE_TYPE -->
<column type="gchararray"/>
+ <!-- column-name add_detail, COL_VPN_ADD_DETAIL -->
+ <column type="gchararray"/>
+ <!-- column-name add_detail_key, COL_VPN_ADD_DETAIL_KEY -->
+ <column type="gchararray"/>
+ <!-- column-name add_detail_val, COL_VPN_ADD_DETAIL_VAL -->
+ <column type="gchararray"/>
</columns>
</object>
<object class="GtkDialog" id="new_connection_type_dialog">
diff --git a/src/connection-editor/connection-helpers.c b/src/connection-editor/connection-helpers.c
index 44921b18..177af4e9 100644
--- a/src/connection-editor/connection-helpers.c
+++ b/src/connection-editor/connection-helpers.c
@@ -43,6 +43,9 @@
#define COL_DESCRIPTION 3
#define COL_VPN_PLUGIN 4
#define COL_VPN_SERVICE_TYPE 5
+#define COL_VPN_ADD_DETAIL 6
+#define COL_VPN_ADD_DETAIL_KEY 7
+#define COL_VPN_ADD_DETAIL_VAL 8
static gint
sort_types (gconstpointer a, gconstpointer b)
@@ -273,9 +276,12 @@ set_up_connection_type_combo (GtkComboBox *combo,
gs_free char *pretty_name = NULL;
gs_free char *description = NULL;
NMVpnEditorPluginServiceFlags flags;
+ gs_strfreev char **add_details_free = NULL;
+ char **add_details;
+ const char *i_add_detail;
if (!nm_vpn_editor_plugin_get_service_info (plugin, service_type, NULL, &pretty_name, &description, &flags)) {
- if (!is_alias)
+ if (is_alias)
goto next;
g_object_get (plugin,
NM_VPN_EDITOR_PLUGIN_NAME, &pretty_name,
@@ -288,21 +294,71 @@ set_up_connection_type_combo (GtkComboBox *combo,
if (!NM_FLAGS_HAS (flags, NM_VPN_EDITOR_PLUGIN_SERVICE_FLAGS_CAN_ADD))
goto next;
- if (show_headers)
- markup = g_markup_printf_escaped (" %s", pretty_name);
- else
- markup = g_markup_escape_text (pretty_name, -1);
-
- gtk_list_store_append (model, &iter);
- gtk_list_store_set (model, &iter,
- COL_MARKUP, markup,
- COL_SENSITIVE, TRUE,
- COL_NEW_FUNC, list[vpn_index].new_connection_func,
- COL_DESCRIPTION, description,
- COL_VPN_PLUGIN, plugin,
- COL_VPN_SERVICE_TYPE, service_type,
- -1);
- g_free (markup);
+ add_details_free = nm_vpn_editor_plugin_get_service_add_details (plugin, service_type);
+ add_details = add_details_free;
+ i_add_detail = add_details ? add_details[0] : NULL;
+ do {
+ const char *i_pretty_name, *i_description;
+ gs_free char *i_pretty_name_free = NULL;
+ gs_free char *i_description_free = NULL;
+ gs_free char *i_add_detail_key = NULL;
+ gs_free char *i_add_detail_val = NULL;
+
+ if (i_add_detail) {
+ if (i_add_detail[0] == '\0')
+ goto i_next;
+ if (!nm_vpn_editor_plugin_get_service_add_detail (plugin, service_type, i_add_detail,
+ &i_pretty_name_free, &i_description_free,
+ &i_add_detail_key, &i_add_detail_val, NULL))
+ goto i_next;
+ if (!i_add_detail_key || i_add_detail_key[0] == '\0') {
+ /* currently, the only way for a plugin to know the add-detail of a new connection
+ * is by returning an "add-detail-key", which then is set in the VPN connection.
+ *
+ * We could imaging other schemes, to notify the plugin which connection is to be
+ * created. This one is sufficient for now, so as is, a plugin must return an
+ * "add-detail-key", otherwise it cannot work. */
+ goto i_next;
+ }
+ if (!i_add_detail_val)
+ i_add_detail_val = g_strdup (i_add_detail);
+ if (!i_add_detail_val[0]) {
+ /* nm_setting_vpn_add_data_item() doesn't allow empty values (??). */
+ goto i_next;
+ }
+ if (!i_pretty_name_free)
+ goto i_next;
+ i_pretty_name = i_pretty_name_free;
+ i_description = i_description_free;
+ } else {
+ i_pretty_name = pretty_name;
+ i_description = description;
+ }
+
+ if (show_headers)
+ markup = g_markup_printf_escaped (" %s", i_pretty_name);
+ else
+ markup = g_markup_escape_text (i_pretty_name, -1);
+
+ gtk_list_store_append (model, &iter);
+ gtk_list_store_set (model, &iter,
+ COL_MARKUP, markup,
+ COL_SENSITIVE, TRUE,
+ COL_NEW_FUNC, list[vpn_index].new_connection_func,
+ COL_DESCRIPTION, i_description,
+ COL_VPN_PLUGIN, plugin,
+ COL_VPN_SERVICE_TYPE, service_type,
+ COL_VPN_ADD_DETAIL, i_add_detail,
+ COL_VPN_ADD_DETAIL_KEY, i_add_detail_key,
+ COL_VPN_ADD_DETAIL_VAL, i_add_detail_val,
+ -1);
+ g_free (markup);
+
+i_next:
+ if (!add_details)
+ break;
+ i_add_detail = (++add_details)[0];
+ } while (i_add_detail);
next:
if (!aliases || !aliases[0])
@@ -426,8 +482,13 @@ new_connection_dialog_full (GtkWindow *parent_window,
int response;
PageNewConnectionFunc new_func = NULL;
gs_free char *vpn_service_type = NULL;
+ gs_free char *vpn_add_detail = NULL;
+ gs_free char *vpn_add_detail_key = NULL;
+ gs_free char *vpn_add_detail_val = NULL;
const char *detail = NULL;
+ gpointer detail_data = NULL;
GError *error = NULL;
+ CEPageVpnDetailData vpn_data;
/* load GUI */
gui = gtk_builder_new ();
@@ -462,16 +523,25 @@ new_connection_dialog_full (GtkWindow *parent_window,
gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter,
COL_NEW_FUNC, &new_func,
COL_VPN_SERVICE_TYPE, &vpn_service_type,
+ COL_VPN_ADD_DETAIL, &vpn_add_detail,
+ COL_VPN_ADD_DETAIL_KEY, &vpn_add_detail_key,
+ COL_VPN_ADD_DETAIL_VAL, &vpn_add_detail_val,
-1);
- if (vpn_service_type)
+ if (vpn_service_type) {
+ memset (&vpn_data, 0, sizeof (vpn_data));
+ vpn_data.add_detail_key = vpn_add_detail_key;
+ vpn_data.add_detail_val = vpn_add_detail_val;
+
detail = vpn_service_type;
+ detail_data = &vpn_data;
+ }
}
gtk_widget_destroy (GTK_WIDGET (type_dialog));
g_object_unref (gui);
if (new_func)
- new_connection_of_type (parent_window, detail, NULL, client, new_func, result_func, user_data);
+ new_connection_of_type (parent_window, detail, detail_data, client, new_func, result_func, user_data);
else
result_func (NULL, user_data);
}
diff --git a/src/connection-editor/page-vpn.c b/src/connection-editor/page-vpn.c
index 4b4a45dd..3d379ecf 100644
--- a/src/connection-editor/page-vpn.c
+++ b/src/connection-editor/page-vpn.c
@@ -290,6 +290,7 @@ vpn_connection_new (GtkWindow *parent,
NMSetting *s_vpn;
const char *service_type;
gs_free char *service_type_free = NULL;
+ const CEPageVpnDetailData *data = detail_data;
if (!detail) {
NewVpnInfo *info;
@@ -319,6 +320,10 @@ vpn_connection_new (GtkWindow *parent,
user_data);
s_vpn = nm_setting_vpn_new ();
g_object_set (s_vpn, NM_SETTING_VPN_SERVICE_TYPE, service_type, NULL);
+
+ if (data && data->add_detail_key)
+ nm_setting_vpn_add_data_item ((NMSettingVpn *) s_vpn, data->add_detail_key, data->add_detail_val);
+
nm_connection_add_setting (connection, s_vpn);
(*result_func) (connection, FALSE, NULL, user_data);
diff --git a/src/connection-editor/page-vpn.h b/src/connection-editor/page-vpn.h
index e8dddf0e..4564efdd 100644
--- a/src/connection-editor/page-vpn.h
+++ b/src/connection-editor/page-vpn.h
@@ -43,6 +43,11 @@ typedef struct {
CEPageClass parent;
} CEPageVpnClass;
+typedef struct {
+ char *add_detail_key;
+ char *add_detail_val;
+} CEPageVpnDetailData;
+
GType ce_page_vpn_get_type (void);
CEPage *ce_page_vpn_new (NMConnectionEditor *editor,