summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-05-19 12:56:47 +0200
committerThomas Haller <thaller@redhat.com>2016-05-19 13:12:43 +0200
commit2c34cd9ab578f488f7d15eed7db3fafd07df17a7 (patch)
tree21dcb517cf7b58f144cd8a10ab50b3ad53404755
parent10ba492047b1ad80adeeb878e7f155a13638da7f (diff)
parent964baa0e3301617ed70b7d16145cb90d8a2f7f1f (diff)
cli: merge branch 'th/cli-vpn-import-fixes-rh1337300'
https://bugzilla.redhat.com/show_bug.cgi?id=1337300 (cherry picked from commit 3d25b2e1a1eb4377d202055e901b51bfb0415f56)
-rw-r--r--clients/cli/connections.c37
-rw-r--r--clients/cli/nmcli-completion13
-rw-r--r--clients/common/nm-vpn-helpers.c131
-rw-r--r--clients/common/nm-vpn-helpers.h7
4 files changed, 144 insertions, 44 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c
index 2db2fcb696..9136d9d6b4 100644
--- a/clients/cli/connections.c
+++ b/clients/cli/connections.c
@@ -53,21 +53,6 @@
#define PROMPT_IP_TUNNEL_MODE _("Tunnel mode: ")
#define PROMPT_MACVLAN_MODE _("MACVLAN mode: ")
-static const char *nmc_known_vpns[] = {
- "openvpn",
- "vpnc",
- "pptp",
- "openconnect",
- "openswan",
- "libreswan",
- "strongswan",
- "ssh",
- "l2tp",
- "iodine",
- "fortisslvpn",
- NULL
-};
-
/* Available fields for 'connection show' */
static NmcOutputField nmc_fields_con_show[] = {
{"NAME", N_("NAME")}, /* 0 */
@@ -5904,10 +5889,12 @@ cleanup_bridge_slave:
const char *user_c = NULL;
char *user = NULL;
const char *st;
- char *service_type = NULL;
+ gs_free char *service_type_free = NULL;
+ const char *service_type = NULL;
nmc_arg_t exp_args[] = { {"vpn-type", TRUE, &vpn_type, !ask},
{"user", TRUE, &user_c, FALSE},
{NULL} };
+ gs_free const char **plugin_names = NULL;
if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error))
return FALSE;
@@ -5922,11 +5909,15 @@ cleanup_bridge_slave:
if (vpn_type_ask)
vpn_type = g_strstrip (vpn_type_ask);
- if (!(st = nmc_string_is_valid (vpn_type, nmc_known_vpns, NULL))) {
+ plugin_names = nm_vpn_get_plugin_names (FALSE);
+ if (!(st = nmc_string_is_valid (vpn_type, plugin_names, NULL))) {
g_print (_("Warning: 'vpn-type': %s not known.\n"), vpn_type);
st = vpn_type;
}
- service_type = g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, st);
+
+ service_type = nm_vpn_get_service_for_name (st);
+ if (!service_type)
+ service_type = service_type_free = nm_vpn_get_service_for_name_default (st);
/* Also ask for all optional arguments if '--ask' is specified. */
user = g_strdup (user_c);
@@ -5943,7 +5934,6 @@ cleanup_bridge_slave:
success = TRUE;
cleanup_vpn:
g_free (vpn_type_ask);
- g_free (service_type);
g_free (user);
if (!success)
return FALSE;
@@ -6711,7 +6701,10 @@ update_connection (gboolean persistent,
static char *
gen_func_vpn_types (const char *text, int state)
{
- return nmc_rl_gen_func_basic (text, state, nmc_known_vpns);
+ gs_free const char **plugin_names = NULL;
+
+ plugin_names = nm_vpn_get_plugin_names (FALSE);
+ return nmc_rl_gen_func_basic (text, state, plugin_names);
}
static char *
@@ -10690,7 +10683,7 @@ do_connection_import (NmCli *nmc, gboolean temporary, int argc, char **argv)
}
/* Import VPN configuration */
- plugin = nm_vpn_get_plugin_by_service (type, &error);
+ plugin = nm_vpn_lookup_plugin (type, NULL, &error);
if (!plugin) {
g_string_printf (nmc->return_text, _("Error: failed to load VPN plugin: %s."),
error->message);
@@ -10797,7 +10790,7 @@ do_connection_export (NmCli *nmc, int argc, char **argv)
type = nm_setting_vpn_get_service_type (nm_connection_get_setting_vpn (connection));
/* Export VPN configuration */
- plugin = nm_vpn_get_plugin_by_service (type, &error);
+ plugin = nm_vpn_lookup_plugin (type, NULL, &error);
if (!plugin) {
g_string_printf (nmc->return_text, _("Error: failed to load VPN plugin: %s."),
error->message);
diff --git a/clients/cli/nmcli-completion b/clients/cli/nmcli-completion
index 3c87f6f9d4..ffab7d8b99 100644
--- a/clients/cli/nmcli-completion
+++ b/clients/cli/nmcli-completion
@@ -494,7 +494,7 @@ _nmcli_compl_ARGS()
;;
vpn-type)
if [[ "${#words[@]}" -eq 2 ]]; then
- _nmcli_list "vpnc openvpn pptp openconnect openswan libreswan ssh l2tp iodine"
+ _nmcli_list "vpnc openvpn pptp openconnect openswan libreswan strongswan ssh l2tp iodine fortisslvpn"
return 0
fi
;;
@@ -579,10 +579,16 @@ _nmcli_compl_ARGS()
user| \
username| \
service| \
- password| \
+ password)
+ if [[ "${#words[@]}" -eq 2 ]]; then
+ return 0
+ fi
+ ;;
passwd-file| \
file)
if [[ "${#words[@]}" -eq 2 ]]; then
+ compopt -o default
+ COMPREPLY=()
return 0
fi
;;
@@ -1379,8 +1385,7 @@ _nmcli()
OPTIONS=(type file)
OPTIONS_MANDATORY=(type file)
- ALIASES=("type:vpn-type")
- _nmcli_compl_ARGS ${ALIASES[@]}
+ _nmcli_compl_ARGS type:vpn-type
return 0
fi
;;
diff --git a/clients/common/nm-vpn-helpers.c b/clients/common/nm-vpn-helpers.c
index 880b6ecdd7..8c7280558c 100644
--- a/clients/common/nm-vpn-helpers.c
+++ b/clients/common/nm-vpn-helpers.c
@@ -36,30 +36,53 @@ static gboolean plugins_loaded;
static GSList *plugins = NULL;
NMVpnEditorPlugin *
-nm_vpn_get_plugin_by_service (const char *service, GError **error)
+nm_vpn_lookup_plugin (const char *name, const char *service, GError **error)
{
NMVpnEditorPlugin *plugin = NULL;
NMVpnPluginInfo *plugin_info;
- char *type = NULL;
+ gs_free_error GError *local = NULL;
- g_return_val_if_fail (service != NULL, NULL);
+ g_return_val_if_fail (!service ^ !name, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
if (G_UNLIKELY (!plugins_loaded))
nm_vpn_get_plugins ();
- if (!g_str_has_prefix (service, NM_DBUS_INTERFACE))
- service = type = g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, service);
+ if (service)
+ plugin_info = nm_vpn_plugin_info_list_find_by_service (plugins, service);
+ else
+ plugin_info = nm_vpn_plugin_info_list_find_by_name (plugins, name);
+
+ if (!plugin_info) {
+ g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
+ _("unknown VPN plugin \"%s\""), service ?: name);
+ return NULL;
+ }
+ plugin = nm_vpn_plugin_info_get_editor_plugin (plugin_info);
+ if (!plugin)
+ plugin = nm_vpn_plugin_info_load_editor_plugin (plugin_info, &local);
+
+ if (!plugin) {
+ if ( !nm_vpn_plugin_info_get_plugin (plugin_info)
+ && nm_vpn_plugin_info_lookup_property (plugin_info, NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "properties")) {
+ g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
+ _("cannot cannot load legacy-only VPN plugin \"%s\" for \"%s\""),
+ nm_vpn_plugin_info_get_name (plugin_info),
+ nm_vpn_plugin_info_get_filename (plugin_info));
+ } else if (g_error_matches (local, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
+ g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
+ _("cannot load VPN plugin \"%s\" due to missing \"%s\". Missing client plugin?"),
+ nm_vpn_plugin_info_get_name (plugin_info),
+ nm_vpn_plugin_info_get_plugin (plugin_info));
+ } else {
+ g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
+ _("failed to load VPN plugin \"%s\": %s"),
+ nm_vpn_plugin_info_get_name (plugin_info),
+ local->message);
+ }
+ return NULL;
+ }
- plugin_info = nm_vpn_plugin_info_list_find_by_service (plugins, service);
- if (plugin_info) {
- plugin = nm_vpn_plugin_info_get_editor_plugin (plugin_info);
- if (!plugin)
- plugin = nm_vpn_plugin_info_load_editor_plugin (plugin_info, error);
- } else
- g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
- _("could not get VPN plugin info"));
- g_free (type);
return plugin;
}
@@ -73,6 +96,78 @@ nm_vpn_get_plugins (void)
return plugins;
}
+static int
+_strcmp_data (gconstpointer a, gconstpointer b, gpointer unused)
+{
+ return strcmp (a, b);
+}
+
+const char **
+nm_vpn_get_plugin_names (gboolean only_available_plugins)
+{
+ GSList *p;
+ const char **list;
+ const char *known_names[] = {
+ "openvpn",
+ "vpnc",
+ "pptp",
+ "openconnect",
+ "openswan",
+ "libreswan",
+ "strongswan",
+ "ssh",
+ "l2tp",
+ "iodine",
+ "fortisslvpn",
+ };
+ guint i, j, k;
+
+ p = nm_vpn_get_plugins ();
+ list = g_new0 (const char *, g_slist_length (p) + G_N_ELEMENTS (known_names) + 1);
+
+ i = 0;
+ for (i = 0; p; p = p->next)
+ list[i++] = nm_vpn_plugin_info_get_name (p->data);
+ if (!only_available_plugins) {
+ for (j = 0; j < G_N_ELEMENTS (known_names); j++)
+ list[i++] = known_names[j];
+ }
+
+ g_qsort_with_data (list, i, sizeof (gpointer), _strcmp_data, NULL);
+
+ /* remove duplicates */
+ for (k = 0, j = 1; j < i; j++) {
+ if (nm_streq (list[k], list[j]))
+ continue;
+ list[k++] = list[j];
+ }
+ list[k++] = NULL;
+
+ return list;
+}
+
+const char *
+nm_vpn_get_service_for_name (const char *name)
+{
+ NMVpnPluginInfo *plugin_info;
+
+ g_return_val_if_fail (name, NULL);
+
+ plugin_info = nm_vpn_plugin_info_list_find_by_name (nm_vpn_get_plugins (), name);
+ if (plugin_info) {
+ /* this only means we have a .name file (NMVpnPluginInfo). Possibly the
+ * NMVpnEditorPlugin is not loadable. */
+ return nm_vpn_plugin_info_get_service (plugin_info);
+ }
+ return NULL;
+}
+
+char *
+nm_vpn_get_service_for_name_default (const char *name)
+{
+ return g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, name);
+}
+
gboolean
nm_vpn_supports_ipv6 (NMConnection *connection)
{
@@ -85,10 +180,12 @@ nm_vpn_supports_ipv6 (NMConnection *connection)
g_return_val_if_fail (s_vpn != NULL, FALSE);
service_type = nm_setting_vpn_get_service_type (s_vpn);
- g_return_val_if_fail (service_type != NULL, FALSE);
+ if (!service_type)
+ return FALSE;
- plugin = nm_vpn_get_plugin_by_service (service_type, NULL);
- g_return_val_if_fail (plugin != NULL, FALSE);
+ plugin = nm_vpn_lookup_plugin (NULL, service_type, NULL);
+ if (!plugin)
+ return FALSE;
capabilities = nm_vpn_editor_plugin_get_capabilities (plugin);
return NM_FLAGS_HAS (capabilities, NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6);
diff --git a/clients/common/nm-vpn-helpers.h b/clients/common/nm-vpn-helpers.h
index 4f8d219441..79fc94e957 100644
--- a/clients/common/nm-vpn-helpers.h
+++ b/clients/common/nm-vpn-helpers.h
@@ -30,7 +30,12 @@ struct {
GSList *nm_vpn_get_plugins (void);
-NMVpnEditorPlugin *nm_vpn_get_plugin_by_service (const char *service, GError **error);
+const char **nm_vpn_get_plugin_names (gboolean only_available_plugins);
+
+const char *nm_vpn_get_service_for_name (const char *name);
+char * nm_vpn_get_service_for_name_default (const char *name);
+
+NMVpnEditorPlugin *nm_vpn_lookup_plugin (const char *name, const char *service, GError **error);
gboolean nm_vpn_supports_ipv6 (NMConnection *connection);