diff options
author | Thomas Haller <thaller@redhat.com> | 2020-05-04 13:33:35 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-05-13 10:28:04 +0200 |
commit | 360f0fae111a76cc47fb559d035096221a3a5993 (patch) | |
tree | 1a4b21a601fda382658ca2dfce409f392923e235 | |
parent | 1086a47cdae5b1e10c7fcf4a4f8242381027f6a1 (diff) | |
download | NetworkManager-360f0fae111a76cc47fb559d035096221a3a5993.tar.gz |
cli: move nmc_utils_read_passwd_file() to "common/nm-client-utils.c"
-rw-r--r-- | clients/cli/connections.c | 180 | ||||
-rw-r--r-- | clients/common/nm-client-utils.c | 180 | ||||
-rw-r--r-- | clients/common/nm-client-utils.h | 4 |
3 files changed, 184 insertions, 180 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c index b2dd0a60a7..a6bbe5669b 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -16,8 +16,6 @@ #include <readline/history.h> #include <fcntl.h> -#include "nm-glib-aux/nm-secret-utils.h" -#include "nm-glib-aux/nm-io-utils.h" #include "nm-client-utils.h" #include "nm-vpn-helpers.h" #include "nm-meta-setting-access.h" @@ -2696,182 +2694,6 @@ activate_connection_cb (GObject *client, GAsyncResult *result, gpointer user_dat } } -/** - * parse_passwords: - * @passwd_file: file with passwords to parse - * @out_error_line: returns in case of a syntax error in the file, the line - * on which it occurred. - * @error: location to store error, or %NULL - * - * Parse passwords given in @passwd_file and insert them into a hash table. - * Example of @passwd_file contents: - * wifi.psk:tajne heslo - * 802-1x.password:krakonos - * 802-11-wireless-security:leap-password:my leap password - * - * Returns: hash table with parsed passwords, or %NULL on an error - */ -static GHashTable * -parse_passwords (const char *passwd_file, - gssize *out_error_line, - GError **error) -{ - nm_auto_clear_secret_ptr NMSecretPtr contents = { 0 }; - gs_unref_hashtable GHashTable *pwds_hash = NULL; - const char *contents_str; - gsize contents_line; - - pwds_hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) nm_free_secret); - - NM_SET_OUT (out_error_line, -1); - - if (!passwd_file) - return g_steal_pointer (&pwds_hash); - - if (!nm_utils_file_get_contents (-1, - passwd_file, - 1024*1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET, - &contents.str, - &contents.len, - NULL, - error)) - return NULL; - - contents_str = contents.str; - contents_line = 0; - while (contents_str[0]) { - nm_auto_free_secret char *l_hash_key = NULL; - nm_auto_free_secret char *l_hash_val = NULL; - const char *l_content_line; - const char *l_setting; - const char *l_prop; - const char *l_val; - const char *s; - gsize l_hash_val_len; - - /* consume first line. As line delimiters we accept "\r\n", "\n", and "\r". */ - l_content_line = contents_str; - s = l_content_line; - while (!NM_IN_SET (s[0], '\0', '\r', '\n')) - s++; - if (s[0] != '\0') { - if ( s[0] == '\r' - && s[1] == '\n') { - ((char *) s)[0] = '\0'; - s += 2; - } else { - ((char *) s)[0] = '\0'; - s += 1; - } - } - contents_str = s; - contents_line++; - - l_content_line = nm_str_skip_leading_spaces (l_content_line); - if (NM_IN_SET (l_content_line[0], '\0', '#')) { - /* a comment or empty line. Ignore. */ - continue; - } - - l_setting = l_content_line; - - s = l_setting; - while (!NM_IN_SET (s[0], '\0', ':', '=')) - s++; - if (s[0] == '\0') { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("missing colon for \"<setting>.<property>:<secret>\" format")); - return NULL; - } - ((char *) s)[0] = '\0'; - s++; - - l_val = s; - - g_strchomp ((char *) l_setting); - - nm_assert (nm_str_is_stripped (l_setting)); - - s = strchr (l_setting, '.'); - if (!s) { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("missing dot for \"<setting>.<property>:<secret>\" format")); - return NULL; - } else if (s == l_setting) { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("missing setting for \"<setting>.<property>:<secret>\" format")); - return NULL; - } - ((char *) s)[0] = '\0'; - s++; - - l_prop = s; - if (l_prop[0] == '\0') { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("missing property for \"<setting>.<property>:<secret>\" format")); - return NULL; - } - - /* Accept wifi-sec or wifi instead of cumbersome '802-11-wireless-security' */ - if (NM_IN_STRSET (l_setting, "wifi-sec", "wifi")) - l_setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; - - if (nm_setting_lookup_type (l_setting) == G_TYPE_INVALID) { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("invalid setting name")); - return NULL; - } - - if ( nm_streq (l_setting, "vpn") - && NM_STR_HAS_PREFIX (l_prop, "secret.")) { - /* in 1.12.0, we wrongly required the VPN secrets to be named - * "vpn.secret". It should be "vpn.secrets". Work around it - * (rh#1628833). */ - l_hash_key = g_strdup_printf ("vpn.secrets.%s", &l_prop[NM_STRLEN ("secret.")]); - } else - l_hash_key = g_strdup_printf ("%s.%s", l_setting, l_prop); - - if (!g_utf8_validate (l_hash_key, -1, NULL)) { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("property name is not UTF-8")); - return NULL; - } - - /* Support backslash escaping in the secret value. We strip non-escaped leading/trailing whitespaces. */ - s = nm_utils_buf_utf8safe_unescape (l_val, NM_UTILS_STR_UTF8_SAFE_UNESCAPE_STRIP_SPACES, &l_hash_val_len, (gpointer *) &l_hash_val); - if (!l_hash_val) - l_hash_val = g_strdup (s); - - if (!g_utf8_validate (l_hash_val, -1, NULL)) { - /* In some cases it might make sense to support binary secrets (like the WPA-PSK which has no - * defined encoding. However, all API that follows can only handle UTF-8, and no mechanism - * to escape the secrets. Reject non-UTF-8 early. */ - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("secret is not UTF-8")); - return NULL; - } - - if (strlen (l_hash_val) != l_hash_val_len) { - NM_SET_OUT (out_error_line, contents_line); - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - _("secret is not UTF-8")); - return NULL; - } - - g_hash_table_insert (pwds_hash, g_steal_pointer (&l_hash_key), g_steal_pointer (&l_hash_val)); - } - - return g_steal_pointer (&pwds_hash); -} - static gboolean nmc_activate_connection (NmCli *nmc, NMConnection *connection, @@ -2924,7 +2746,7 @@ nmc_activate_connection (NmCli *nmc, gs_free_error GError *local = NULL; gssize error_line; - pwds_hash = parse_passwords (pwds, &error_line, &local); + pwds_hash = nmc_utils_read_passwd_file (pwds, &error_line, &local); if (!pwds_hash) { if (error_line >= 0) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, diff --git a/clients/common/nm-client-utils.c b/clients/common/nm-client-utils.c index cf8b478560..a296a3b9dc 100644 --- a/clients/common/nm-client-utils.c +++ b/clients/common/nm-client-utils.c @@ -6,8 +6,10 @@ #include "nm-default.h" #include "nm-client-utils.h" -#include "nm-utils.h" +#include "nm-glib-aux/nm-secret-utils.h" +#include "nm-glib-aux/nm-io-utils.h" +#include "nm-utils.h" #include "nm-device-bond.h" #include "nm-device-bridge.h" #include "nm-device-team.h" @@ -587,3 +589,179 @@ nmc_print_qrcode (const char *str) } } } + +/** + * nmc_utils_read_passwd_file: + * @passwd_file: file with passwords to parse + * @out_error_line: returns in case of a syntax error in the file, the line + * on which it occurred. + * @error: location to store error, or %NULL + * + * Parse passwords given in @passwd_file and insert them into a hash table. + * Example of @passwd_file contents: + * wifi.psk:tajne heslo + * 802-1x.password:krakonos + * 802-11-wireless-security:leap-password:my leap password + * + * Returns: (transfer full): hash table with parsed passwords, or %NULL on an error + */ +GHashTable * +nmc_utils_read_passwd_file (const char *passwd_file, + gssize *out_error_line, + GError **error) +{ + nm_auto_clear_secret_ptr NMSecretPtr contents = { 0 }; + gs_unref_hashtable GHashTable *pwds_hash = NULL; + const char *contents_str; + gsize contents_line; + + pwds_hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, (GDestroyNotify) nm_free_secret); + + NM_SET_OUT (out_error_line, -1); + + if (!passwd_file) + return g_steal_pointer (&pwds_hash); + + if (!nm_utils_file_get_contents (-1, + passwd_file, + 1024*1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET, + &contents.str, + &contents.len, + NULL, + error)) + return NULL; + + contents_str = contents.str; + contents_line = 0; + while (contents_str[0]) { + nm_auto_free_secret char *l_hash_key = NULL; + nm_auto_free_secret char *l_hash_val = NULL; + const char *l_content_line; + const char *l_setting; + const char *l_prop; + const char *l_val; + const char *s; + gsize l_hash_val_len; + + /* consume first line. As line delimiters we accept "\r\n", "\n", and "\r". */ + l_content_line = contents_str; + s = l_content_line; + while (!NM_IN_SET (s[0], '\0', '\r', '\n')) + s++; + if (s[0] != '\0') { + if ( s[0] == '\r' + && s[1] == '\n') { + ((char *) s)[0] = '\0'; + s += 2; + } else { + ((char *) s)[0] = '\0'; + s += 1; + } + } + contents_str = s; + contents_line++; + + l_content_line = nm_str_skip_leading_spaces (l_content_line); + if (NM_IN_SET (l_content_line[0], '\0', '#')) { + /* a comment or empty line. Ignore. */ + continue; + } + + l_setting = l_content_line; + + s = l_setting; + while (!NM_IN_SET (s[0], '\0', ':', '=')) + s++; + if (s[0] == '\0') { + NM_SET_OUT (out_error_line, contents_line); + nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, + _("missing colon for \"<setting>.<property>:<secret>\" format")); + return NULL; + } + ((char *) s)[0] = '\0'; + s++; + + l_val = s; + + g_strchomp ((char *) l_setting); + + nm_assert (nm_str_is_stripped (l_setting)); + + s = strchr (l_setting, '.'); + if (!s) { + NM_SET_OUT (out_error_line, contents_line); + nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, + _("missing dot for \"<setting>.<property>:<secret>\" format")); + return NULL; + } else if (s == l_setting) { + NM_SET_OUT (out_error_line, contents_line); + nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, + _("missing setting for \"<setting>.<property>:<secret>\" format")); + return NULL; + } + ((char *) s)[0] = '\0'; + s++; + + l_prop = s; + if (l_prop[0] == '\0') { + NM_SET_OUT (out_error_line, contents_line); + nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, + _("missing property for \"<setting>.<property>:<secret>\" format")); + return NULL; + } + + /* Accept wifi-sec or wifi instead of cumbersome '802-11-wireless-security' */ + if (NM_IN_STRSET (l_setting, "wifi-sec", "wifi")) + l_setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; + + if (nm_setting_lookup_type (l_setting) == G_TYPE_INVALID) { + NM_SET_OUT (out_error_line, contents_line); + nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, + _("invalid setting name")); + return NULL; + } + + if ( nm_streq (l_setting, "vpn") + && NM_STR_HAS_PREFIX (l_prop, "secret.")) { + /* in 1.12.0, we wrongly required the VPN secrets to be named + * "vpn.secret". It should be "vpn.secrets". Work around it + * (rh#1628833). */ + l_hash_key = g_strdup_printf ("vpn.secrets.%s", &l_prop[NM_STRLEN ("secret.")]); + } else + l_hash_key = g_strdup_printf ("%s.%s", l_setting, l_prop); + + if (!g_utf8_validate (l_hash_key, -1, NULL)) { + NM_SET_OUT (out_error_line, contents_line); + nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, + _("property name is not UTF-8")); + return NULL; + } + + /* Support backslash escaping in the secret value. We strip non-escaped leading/trailing whitespaces. */ + s = nm_utils_buf_utf8safe_unescape (l_val, NM_UTILS_STR_UTF8_SAFE_UNESCAPE_STRIP_SPACES, &l_hash_val_len, (gpointer *) &l_hash_val); + if (!l_hash_val) + l_hash_val = g_strdup (s); + + if (!g_utf8_validate (l_hash_val, -1, NULL)) { + /* In some cases it might make sense to support binary secrets (like the WPA-PSK which has no + * defined encoding. However, all API that follows can only handle UTF-8, and no mechanism + * to escape the secrets. Reject non-UTF-8 early. */ + NM_SET_OUT (out_error_line, contents_line); + nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, + _("secret is not UTF-8")); + return NULL; + } + + if (strlen (l_hash_val) != l_hash_val_len) { + NM_SET_OUT (out_error_line, contents_line); + nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, + _("secret is not UTF-8")); + return NULL; + } + + g_hash_table_insert (pwds_hash, g_steal_pointer (&l_hash_key), g_steal_pointer (&l_hash_val)); + } + + return g_steal_pointer (&pwds_hash); +} diff --git a/clients/common/nm-client-utils.h b/clients/common/nm-client-utils.h index 1e3085d56d..f4f67544e7 100644 --- a/clients/common/nm-client-utils.h +++ b/clients/common/nm-client-utils.h @@ -43,4 +43,8 @@ const char *nmc_password_subst_char (void); void nmc_print_qrcode (const char *str); +GHashTable *nmc_utils_read_passwd_file (const char *passwd_file, + gssize *out_error_line, + GError **error); + #endif /* __NM_CLIENT_UTILS_H__ */ |