From ee96387578ca5428b9836dda382f9e6d64d5a7a8 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 23 Apr 2019 14:17:47 +0200 Subject: [PATCH 1/6] cli: fix setting private key password Fixes: fe390556abfe ('cli: add property type for 802-1x certificate properties (pt3)') --- clients/common/nm-meta-setting-desc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 98cb50405c..b24eb17c2d 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -2263,6 +2263,7 @@ _set_fcn_cert_8021x (ARGS_SET_FCN) password = path + strcspn (path, " \t"); if (password[0] != '\0') { password[0] = '\0'; + password++; while (nm_utils_is_separator (password[0])) password++; } else { From eac15501b2364a20505a90661e037a339a63b0ea Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 23 Apr 2019 14:55:32 +0200 Subject: [PATCH 2/6] cli: parse escape sequences when reading an 802.1x private key In this way it become possible to specify a filename that includes one of the delimiters. --- clients/common/nm-meta-setting-desc.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index b24eb17c2d..858c8a5312 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -2255,17 +2255,25 @@ _set_fcn_cert_8021x (ARGS_SET_FCN) vtable = &nm_setting_8021x_scheme_vtable[property_info->property_typ_data->subtype.cert_8021x.scheme_type]; if (vtable->is_secret) { - gs_free char *path = NULL; nm_auto_free_secret char *password_free = NULL; - char *password; + gs_free const char **strv = NULL; + const char *password; + const char *path; + gsize len; - path = g_strdup (value); - password = path + strcspn (path, " \t"); - if (password[0] != '\0') { - password[0] = '\0'; - password++; - while (nm_utils_is_separator (password[0])) - password++; + strv = nm_utils_escaped_tokens_split (value, NM_ASCII_SPACES); + len = NM_PTRARRAY_LEN (strv); + if (len > 2) { + g_set_error_literal (error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("too many arguments. Please only specify a private key file and optionally a password")); + return FALSE; + } + + path = len > 0 ? strv[0] : NULL; + if (len == 2) { + password = strv[1]; } else { password_free = g_strdup (vtable->passwd_func (NM_SETTING_802_1X (setting))); password = password_free; From 78b9448b69d1e511aab9f24f4da8a6731c2dc7ee Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 23 Apr 2019 21:14:31 +0200 Subject: [PATCH 3/6] cli: remove bluetooth completion code The 'bt-type' property alias accepts values provided by gen_func_bt_type(); instead the 'bluetooth.type' property can only be set to [dun, panu, nap] and therefore it doesn't need special handling. --- clients/cli/connections.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 2c4b8d2478..282cbe06f0 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -4561,14 +4561,8 @@ complete_property (const char *setting_name, const char *property, const char *p const NMMetaPropertyInfo *property_info; property_info = nm_meta_property_info_find_by_name (setting_name, property); - if (property_info) { - if (complete_option ((const NMMetaAbstractInfo *) property_info, prefix, connection)) - return; - } - - if ( strcmp (setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0 - && strcmp (property, NM_SETTING_BLUETOOTH_TYPE) == 0) - run_rl_generator (gen_func_bt_type, prefix); + if (property_info) + complete_option ((const NMMetaAbstractInfo *) property_info, prefix, connection); } /*****************************************************************************/ From eb724293c25038c7e0f0d6789af2cea11da176eb Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 23 Apr 2019 21:35:19 +0200 Subject: [PATCH 4/6] cli: allow completing filenames Allow the completion function to indicate that the word should be completed as a filename by the shell. --- clients/cli/connections.c | 23 ++++++++++++++++------- clients/common/nm-meta-setting-access.c | 2 ++ clients/common/nm-meta-setting-access.h | 1 + clients/common/nm-meta-setting-desc.c | 4 +++- clients/common/nm-meta-setting-desc.h | 2 ++ 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 282cbe06f0..4b484e7bee 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -3785,6 +3785,7 @@ _meta_abstract_complete (const NMMetaAbstractInfo *abstract_info, const char *te nmc_meta_environment_arg, &ctx, text, + NULL, &values_to_free); if (values) return values_to_free ?: g_strdupv ((char **) values); @@ -4525,11 +4526,12 @@ run_rl_generator (rl_compentry_func_t *generator_func, const char *prefix) } static gboolean -complete_option (const NMMetaAbstractInfo *abstract_info, const char *prefix, NMConnection *context_connection) +complete_option (NmCli *nmc, const NMMetaAbstractInfo *abstract_info, const char *prefix, NMConnection *context_connection) { const OptionInfo *candidate; const char *const*values; gs_strfreev char **values_to_free = NULL; + gboolean complete_filename = FALSE; const NMMetaOperationContext ctx = { .connection = context_connection, }; @@ -4539,7 +4541,12 @@ complete_option (const NMMetaAbstractInfo *abstract_info, const char *prefix, NM nmc_meta_environment_arg, &ctx, prefix, + &complete_filename, &values_to_free); + if (complete_filename) { + nmc->return_value = NMC_RESULT_COMPLETE_FILE; + return TRUE; + } if (values) { for (; values[0]; values++) g_print ("%s\n", values[0]); @@ -4556,13 +4563,13 @@ complete_option (const NMMetaAbstractInfo *abstract_info, const char *prefix, NM } static void -complete_property (const char *setting_name, const char *property, const char *prefix, NMConnection *connection) +complete_property (NmCli *nmc, const char *setting_name, const char *property, const char *prefix, NMConnection *connection) { const NMMetaPropertyInfo *property_info; property_info = nm_meta_property_info_find_by_name (setting_name, property); if (property_info) - complete_option ((const NMMetaAbstractInfo *) property_info, prefix, connection); + complete_option (nmc, (const NMMetaAbstractInfo *) property_info, prefix, connection); } /*****************************************************************************/ @@ -4652,8 +4659,10 @@ nmc_read_connection_properties (NmCli *nmc, if (!get_value (&value, argc, argv, option, error)) return FALSE; - if (!*argc && nmc->complete) - complete_property (setting, strv[1], value ?: "", connection); + if (!*argc && nmc->complete) { + complete_property (nmc, setting, strv[1], value ?: "", connection); + return TRUE; + } if (!set_property (nmc->client, connection, setting_name, strv[1], value, modifier, error)) return FALSE; @@ -4734,7 +4743,7 @@ nmc_read_connection_properties (NmCli *nmc, return FALSE; if (!*argc && nmc->complete) - complete_option (chosen, value ?: "", connection); + complete_option (nmc, chosen, value ?: "", connection); if (!set_option (nmc, connection, chosen, value, error)) return FALSE; @@ -8863,7 +8872,7 @@ do_connection_import (NmCli *nmc, int argc, char **argv) if ( argc == 1 && nmc->complete) { nmc_complete_strings (*argv, "wireguard"); - complete_option ((const NMMetaAbstractInfo *) nm_meta_property_info_vpn_service_type, + complete_option (nmc, (const NMMetaAbstractInfo *) nm_meta_property_info_vpn_service_type, *argv, NULL); } diff --git a/clients/common/nm-meta-setting-access.c b/clients/common/nm-meta-setting-access.c index 8399f29db1..ce5cd331c8 100644 --- a/clients/common/nm-meta-setting-access.c +++ b/clients/common/nm-meta-setting-access.c @@ -273,6 +273,7 @@ nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info, gpointer environment_user_data, const NMMetaOperationContext *operation_context, const char *text, + gboolean *out_complete_filename, char ***out_to_free) { const char *const*values; @@ -292,6 +293,7 @@ nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info, environment_user_data, operation_context, text, + out_complete_filename, out_to_free); nm_assert (!*out_to_free || values == (const char *const*) *out_to_free); diff --git a/clients/common/nm-meta-setting-access.h b/clients/common/nm-meta-setting-access.h index ec1c2ba00a..38f22c7a49 100644 --- a/clients/common/nm-meta-setting-access.h +++ b/clients/common/nm-meta-setting-access.h @@ -69,6 +69,7 @@ const char *const*nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abst gpointer environment_user_data, const NMMetaOperationContext *operation_context, const char *text, + gboolean *out_complete_filename, char ***out_to_free); /*****************************************************************************/ diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 858c8a5312..d70cf3c9a1 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -657,7 +657,7 @@ _env_warn_fcn (const NMMetaEnvironment *environment, const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, GError **error #define ARGS_COMPLETE_FCN \ - const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, const NMMetaOperationContext *operation_context, const char *text, char ***out_to_free + const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, const NMMetaOperationContext *operation_context, const char *text, gboolean *out_complete_filename, char ***out_to_free #define ARGS_VALUES_FCN \ const NMMetaPropertyInfo *property_info, char ***out_to_free @@ -8131,6 +8131,7 @@ _meta_type_property_info_complete_fcn (const NMMetaAbstractInfo *abstract_info, gpointer environment_user_data, const NMMetaOperationContext *operation_context, const char *text, + gboolean *out_complete_filename, char ***out_to_free) { const NMMetaPropertyInfo *info = (const NMMetaPropertyInfo *) abstract_info; @@ -8143,6 +8144,7 @@ _meta_type_property_info_complete_fcn (const NMMetaAbstractInfo *abstract_info, environment_user_data, operation_context, text, + out_complete_filename, out_to_free); } diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 2178f747bb..f075439b70 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -221,6 +221,7 @@ struct _NMMetaPropertyType { gpointer environment_user_data, const NMMetaOperationContext *operation_context, const char *text, + gboolean *out_complete_filename, char ***out_to_free); /* Whether set_fcn() supports the '-' modifier. That is, whether the property @@ -451,6 +452,7 @@ struct _NMMetaType { gpointer environment_user_data, const NMMetaOperationContext *operation_context, const char *text, + gboolean *out_complete_filename, char ***out_to_free); }; From ec4a12ecdbebbca5b8108e1611e95fa93b43d637 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 23 Apr 2019 22:01:15 +0200 Subject: [PATCH 5/6] cli: complete 802.1x certificate file names --- clients/common/nm-meta-setting-desc.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index d70cf3c9a1..c7a7fe54bb 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -2294,6 +2294,26 @@ _set_fcn_cert_8021x (ARGS_SET_FCN) } } +static const char *const* +_complete_fcn_cert_8021x (ARGS_COMPLETE_FCN) +{ + const NMSetting8021xSchemeVtable *vtable; + + vtable = &nm_setting_8021x_scheme_vtable[property_info->property_typ_data->subtype.cert_8021x.scheme_type]; + + if (vtable->is_secret) { + gs_free const char **strv = NULL; + + strv = nm_utils_escaped_tokens_split (text, NM_ASCII_SPACES); + /* don't try to complete the password */ + if (NM_PTRARRAY_LEN (strv) > 1) + return NULL; + } + + NM_SET_OUT (out_complete_filename, TRUE); + return NULL; +} + static gconstpointer _get_fcn_bond_options (ARGS_GET_FCN) { @@ -4437,6 +4457,7 @@ static const NMMetaPropertyType _pt_dcb = { static const NMMetaPropertyType _pt_cert_8021x = { .get_fcn = _get_fcn_cert_8021x, .set_fcn = _set_fcn_cert_8021x, + .complete_fcn = _complete_fcn_cert_8021x, }; static const NMMetaPropertyType _pt_ethtool = { From c91aad49695fc0d5ff1dd07a4459dc7fbe9bdbc0 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Wed, 24 Apr 2019 15:21:34 +0200 Subject: [PATCH 6/6] cli: hide certificate blobs unless --show-secrets is passed This restores the behavior before commit 99711579ed43. Fixes: 99711579ed43 ('cli: add property type for 802-1x certificate properties (pt2)'). --- clients/common/nm-meta-setting-desc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index c7a7fe54bb..cc3557d6fa 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -2216,8 +2216,7 @@ _get_fcn_cert_8021x (ARGS_GET_FCN) switch (vtable->scheme_func (s_8021X)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: - if ( vtable->is_secret - && !NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) + if (!NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) return _get_text_hidden (get_type); str = bytes_to_string (vtable->blob_func (s_8021X)); break;