diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/NetworkManagerUtils.c | 117 | ||||
-rw-r--r-- | src/NetworkManagerUtils.h | 6 | ||||
-rw-r--r-- | src/dhcp-manager/nm-dhcp-listener.c | 3 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 7 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 3 | ||||
-rw-r--r-- | src/settings/plugins/ibft/reader.c | 18 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/reader.c | 6 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/shvar.c | 6 | ||||
-rw-r--r-- | src/settings/plugins/ifnet/connection_parser.c | 8 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/common.h | 2 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/reader.c | 1333 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Blob | 4 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old | 6 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/tests/test-keyfile.c | 54 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/utils.c | 175 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/utils.h | 51 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/writer.c | 736 | ||||
-rw-r--r-- | src/settings/plugins/keyfile/writer.h | 1 | ||||
-rw-r--r-- | src/tests/test-general.c | 178 |
19 files changed, 207 insertions, 2507 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 67633bccef..57f817649e 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -1798,123 +1798,6 @@ nm_utils_cmp_connection_by_autoconnect_priority (NMConnection **a, NMConnection return 0; } -/* nm_utils_ascii_str_to_int64: - * - * A wrapper for g_ascii_strtoll, that checks whether the whole string - * can be successfully converted to a number and is within a given - * range. On any error, @fallback will be returned and %errno will be set - * to a non-zero value. On success, %errno will be set to zero, check %errno - * for errors. Any trailing or leading (ascii) white space is ignored and the - * functions is locale independent. - * - * The function is guaranteed to return a value between @min and @max - * (inclusive) or @fallback. Also, the parsing is rather strict, it does - * not allow for any unrecognized characters, except leading and trailing - * white space. - **/ -gint64 -nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback) -{ - gint64 v; - size_t len; - char buf[64], *s, *str_free = NULL; - - if (str) { - while (g_ascii_isspace (str[0])) - str++; - } - if (!str || !str[0]) { - errno = EINVAL; - return fallback; - } - - len = strlen (str); - if (g_ascii_isspace (str[--len])) { - /* backward search the first non-ws character. - * We already know that str[0] is non-ws. */ - while (g_ascii_isspace (str[--len])) - ; - - /* str[len] is now the last non-ws character... */ - len++; - - if (len >= sizeof (buf)) - s = str_free = g_malloc (len + 1); - else - s = buf; - - memcpy (s, str, len); - s[len] = 0; - - /* - g_assert (len > 0 && len < strlen (str) && len == strlen (s)); - g_assert (!g_ascii_isspace (str[len-1]) && g_ascii_isspace (str[len])); - g_assert (strncmp (str, s, len) == 0); - */ - - str = s; - } - - errno = 0; - v = g_ascii_strtoll (str, &s, base); - - if (errno != 0) - v = fallback; - else if (s[0] != 0) { - errno = EINVAL; - v = fallback; - } else if (v > max || v < min) { - errno = ERANGE; - v = fallback; - } - - if (G_UNLIKELY (str_free)) - g_free (str_free); - return v; -} - -/** - * nm_utils_uuid_generate_from_strings: - * @string1: a variadic list of strings. Must be NULL terminated. - * - * Returns a variant3 UUID based on the concatenated C strings. - * It does not simply concatenate them, but also includes the - * terminating '\0' character. For example "a", "b", gives - * "a\0b\0". - * - * This has the advantage, that the following invocations - * all give different UUIDs: (NULL), (""), ("",""), ("","a"), ("a",""), - * ("aa"), ("aa", ""), ("", "aa"), ... - */ -char * -nm_utils_uuid_generate_from_strings (const char *string1, ...) -{ - GString *str; - va_list args; - const char *s; - char *uuid; - - if (!string1) - return nm_utils_uuid_generate_from_string (NULL, 0, NM_UTILS_UUID_TYPE_VARIANT3, NM_UTILS_UUID_NS); - - str = g_string_sized_new (120); /* effectively allocates power of 2 (128)*/ - - g_string_append_len (str, string1, strlen (string1) + 1); - - va_start (args, string1); - s = va_arg (args, const char *); - while (s) { - g_string_append_len (str, s, strlen (s) + 1); - s = va_arg (args, const char *); - } - va_end (args); - - uuid = nm_utils_uuid_generate_from_string (str->str, str->len, NM_UTILS_UUID_TYPE_VARIANT3, NM_UTILS_UUID_NS); - - g_string_free (str, TRUE); - return uuid; -} - /**************************************************************************/ static gint64 monotonic_timestamp_offset_sec; diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 25b3e27a0d..23d8330a34 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -163,12 +163,6 @@ int nm_utils_cmp_connection_by_autoconnect_priority (NMConnection **a, NMConnect void nm_utils_log_connection_diff (NMConnection *connection, NMConnection *diff_base, guint32 level, guint64 domain, const char *name, const char *prefix); -gint64 nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback); - -#define NM_UTILS_UUID_NS "b425e9fb-7598-44b4-9e3b-5a2e3aaa4905" - -char *nm_utils_uuid_generate_from_strings (const char *string1, ...) G_GNUC_NULL_TERMINATED; - #define NM_UTILS_NS_PER_SECOND ((gint64) 1000000000) gint64 nm_utils_get_monotonic_timestamp_ns (void); gint64 nm_utils_get_monotonic_timestamp_us (void); diff --git a/src/dhcp-manager/nm-dhcp-listener.c b/src/dhcp-manager/nm-dhcp-listener.c index bb29717a97..ca57ae595a 100644 --- a/src/dhcp-manager/nm-dhcp-listener.c +++ b/src/dhcp-manager/nm-dhcp-listener.c @@ -31,6 +31,7 @@ #include <unistd.h> #include "nm-dhcp-listener.h" +#include "nm-core-internal.h" #include "nm-logging.h" #include "nm-dbus-manager.h" #include "nm-dbus-glib-types.h" @@ -132,7 +133,7 @@ handle_event (DBusGProxy *proxy, } pid_str = get_option (options, "pid"); - pid = nm_utils_ascii_str_to_int64 (pid_str, 10, 0, G_MAXINT32, -1); + pid = _nm_utils_ascii_str_to_int64 (pid_str, 10, 0, G_MAXINT32, -1); if (pid == -1) { nm_log_warn (LOGD_DHCP, "DHCP event: couldn't convert PID '%s' to an integer", pid_str ? pid_str : "(null)"); goto out; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index e1887e5a4b..47075f226f 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -55,6 +55,7 @@ #endif #include "gsystem-local-alloc.h" +#include "nm-core-internal.h" #include "NetworkManagerUtils.h" #include "nm-linux-platform.h" #include "NetworkManagerUtils.h" @@ -3025,7 +3026,7 @@ tun_get_properties (NMPlatform *platform, int ifindex, NMPlatformTunProperties * val = nm_platform_sysctl_get (path); g_free (path); if (val) { - props->owner = nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1); + props->owner = _nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1); if (errno) success = FALSE; g_free (val); @@ -3036,7 +3037,7 @@ tun_get_properties (NMPlatform *platform, int ifindex, NMPlatformTunProperties * val = nm_platform_sysctl_get (path); g_free (path); if (val) { - props->group = nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1); + props->group = _nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1); if (errno) success = FALSE; g_free (val); @@ -3049,7 +3050,7 @@ tun_get_properties (NMPlatform *platform, int ifindex, NMPlatformTunProperties * if (val) { gint64 flags; - flags = nm_utils_ascii_str_to_int64 (val, 16, 0, G_MAXINT64, 0); + flags = _nm_utils_ascii_str_to_int64 (val, 16, 0, G_MAXINT64, 0); if (!errno) { #ifndef IFF_MULTI_QUEUE const int IFF_MULTI_QUEUE = 0x0100; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index cbf2c8cd61..9500a75424 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -35,6 +35,7 @@ #include "NetworkManagerUtils.h" #include "nm-logging.h" #include "nm-enum-types.h" +#include "nm-core-internal.h" #define debug(...) nm_log_dbg (LOGD_PLATFORM, __VA_ARGS__) @@ -322,7 +323,7 @@ nm_platform_sysctl_get_int_checked (const char *path, guint base, gint64 min, gi return fallback; } - ret = nm_utils_ascii_str_to_int64 (value, base, min, max, fallback); + ret = _nm_utils_ascii_str_to_int64 (value, base, min, max, fallback); g_free (value); return ret; } diff --git a/src/settings/plugins/ibft/reader.c b/src/settings/plugins/ibft/reader.c index e3a0168a6c..9bc6346278 100644 --- a/src/settings/plugins/ibft/reader.c +++ b/src/settings/plugins/ibft/reader.c @@ -397,13 +397,13 @@ connection_setting_add (const GPtrArray *block, prefix ? prefix : "", iface); - uuid = nm_utils_uuid_generate_from_strings ("ibft", - s_hwaddr, - s_vlanid ? "V" : "v", - s_vlanid ? s_vlanid : "", - s_ip4addr ? "A" : "DHCP", - s_ip4addr ? s_ip4addr : "", - NULL); + uuid = _nm_utils_uuid_generate_from_strings ("ibft", + s_hwaddr, + s_vlanid ? "V" : "v", + s_vlanid ? s_vlanid : "", + s_ip4addr ? "A" : "DHCP", + s_ip4addr ? s_ip4addr : "", + NULL); s_con = nm_setting_connection_new (); g_object_set (s_con, @@ -431,7 +431,7 @@ is_ibft_vlan_device (const GPtrArray *block) /* VLAN 0 is normally a valid VLAN ID, but in the iBFT case it * means "no VLAN". */ - if (nm_utils_ascii_str_to_int64 (s_vlan_id, 10, 1, 4095, -1) != -1) + if (_nm_utils_ascii_str_to_int64 (s_vlan_id, 10, 1, 4095, -1) != -1) return TRUE; } return FALSE; @@ -458,7 +458,7 @@ vlan_setting_add_from_block (const GPtrArray *block, g_assert (vlan_id_str); /* VLAN 0 is normally a valid VLAN ID, but in the iBFT case it means "no VLAN" */ - vlan_id = nm_utils_ascii_str_to_int64 (vlan_id_str, 10, 1, 4095, -1); + vlan_id = _nm_utils_ascii_str_to_int64 (vlan_id_str, 10, 1, 4095, -1); if (vlan_id == -1) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid VLAN_ID '%s'", vlan_id_str); diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index c40fecf50b..febbd90ac6 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -503,7 +503,7 @@ read_one_ip4_route (shvarFile *ifcfg, /* Metric */ value = svGetValue (ifcfg, metric_tag, FALSE); if (value) { - metric = nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, -1); + metric = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, -1); if (metric < 0) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP4 route metric '%s'", value); @@ -3344,7 +3344,7 @@ make_wireless_setting (shvarFile *ifcfg, value = svGetValue (ifcfg, "CHANNEL", FALSE); if (value) { errno = 0; - chan = nm_utils_ascii_str_to_int64 (value, 10, 1, 196, 0); + chan = _nm_utils_ascii_str_to_int64 (value, 10, 1, 196, 0); if (errno || (chan == 0)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid wireless channel '%s'", value); @@ -4889,7 +4889,7 @@ devtimeout_from_file (const char *filename) devtimeout_str = svGetValue (ifcfg, "DEVTIMEOUT", FALSE); if (devtimeout_str) { - devtimeout = nm_utils_ascii_str_to_int64 (devtimeout_str, 10, 0, G_MAXUINT, 0); + devtimeout = _nm_utils_ascii_str_to_int64 (devtimeout_str, 10, 0, G_MAXUINT, 0); g_free (devtimeout_str); } else devtimeout = 0; diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index 5f3d173b2a..ed12683072 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -36,7 +36,7 @@ #include "shvar.h" -#include "NetworkManagerUtils.h" +#include "nm-core-internal.h" #include "nm-logging.h" #define PARSE_WARNING(msg...) nm_log_warn (LOGD_SETTINGS, " " msg) @@ -321,7 +321,7 @@ svTrueValue (shvarFile *s, const char *key, gboolean def) * @max: the maximum for range-check * @fallback: the fallback value in any error case * - * Reads a value @key and converts it to an integer using nm_utils_ascii_str_to_int64(). + * Reads a value @key and converts it to an integer using _nm_utils_ascii_str_to_int64(). * In case of error, @errno will be set and @fallback returned. */ gint64 svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 max, gint64 fallback) @@ -336,7 +336,7 @@ svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 m return fallback; } - result = nm_utils_ascii_str_to_int64 (tmp, base, min, max, fallback); + result = _nm_utils_ascii_str_to_int64 (tmp, base, min, max, fallback); errsv = errno; if (errsv != 0) PARSE_WARNING ("Error reading '%s' value '%s' as integer (%d)", key, tmp, errsv); diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c index 41baf31507..888ee589ad 100644 --- a/src/settings/plugins/ifnet/connection_parser.c +++ b/src/settings/plugins/ifnet/connection_parser.c @@ -706,13 +706,13 @@ make_ip4_setting (NMConnection *connection, GError *local = NULL; if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) { - metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); + metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); } else { metric_str = ifnet_get_global_data ("metric"); if (metric_str) { stripped = g_strdup (metric_str); strip_string (stripped, '"'); - metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); + metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); g_free (stripped); } else metric = -1; @@ -846,13 +846,13 @@ make_ip6_setting (NMConnection *connection, /* metric is not per routes configuration right now * global metric is also supported (metric="x") */ if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) - metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); + metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); else { metric_str = ifnet_get_global_data ("metric"); if (metric_str) { stripped = g_strdup (metric_str); strip_string (stripped, '"'); - metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); + metric = _nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); g_free (stripped); } else metric = 1; diff --git a/src/settings/plugins/keyfile/common.h b/src/settings/plugins/keyfile/common.h index 7bde4bf3a9..86fe002855 100644 --- a/src/settings/plugins/keyfile/common.h +++ b/src/settings/plugins/keyfile/common.h @@ -28,7 +28,5 @@ #define KEYFILE_DIR NMCONFDIR "/system-connections" -#define VPN_SECRETS_GROUP "vpn-secrets" - #endif /* __COMMON_H__ */ diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c index 1a1d9663d3..a149e06d93 100644 --- a/src/settings/plugins/keyfile/reader.c +++ b/src/settings/plugins/keyfile/reader.c @@ -15,1239 +15,76 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2009 Novell, Inc. - * Copyright (C) 2008 - 2011 Red Hat, Inc. + * Copyright (C) 2015 Red Hat, Inc. */ #include "config.h" -#include <errno.h> -#include <stdlib.h> #include <sys/stat.h> -#include <unistd.h> -#include <sys/types.h> -#include <arpa/inet.h> #include <string.h> -#include "nm-core-internal.h" -#include "nm-dbus-glib-types.h" -#include "nm-glib-compat.h" -#include "nm-system-config-interface.h" -#include "nm-logging.h" #include "reader.h" -#include "common.h" -#include "utils.h" -#include "nm-core-internal.h" -#include "NetworkManagerUtils.h" - -/* Some setting properties also contain setting names, such as - * NMSettingConnection's 'type' property (which specifies the base type of the - * connection, e.g. ethernet or wifi) or 'slave-type' (specifies type of slave - * connection, e.g. bond or bridge). This function handles translating those - * properties' values to the real setting name if they are an alias. - */ -static void -setting_alias_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) -{ - const char *setting_name = nm_setting_get_name (setting); - char *s; - const char *key_setting_name; - - s = nm_keyfile_plugin_kf_get_string (keyfile, setting_name, key, NULL); - if (s) { - key_setting_name = nm_keyfile_plugin_get_setting_name_for_alias (s); - g_object_set (G_OBJECT (setting), - key, key_setting_name ? key_setting_name : s, - NULL); - g_free (s); - } -} - -static gboolean -read_array_of_uint (GKeyFile *file, - NMSetting *setting, - const char *key) -{ - GArray *array = NULL; - gsize length; - int i; - gint *tmp; - - tmp = nm_keyfile_plugin_kf_get_integer_list (file, nm_setting_get_name (setting), key, &length, NULL); - array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length); - g_return_val_if_fail (array != NULL, FALSE); - - for (i = 0; i < length; i++) - g_array_append_val (array, tmp[i]); - - g_object_set (setting, key, array, NULL); - g_array_unref (array); - - return TRUE; -} - -static gboolean -get_one_int (const char *str, guint32 max_val, const char *key_name, guint32 *out) -{ - long tmp; - char *endptr; - - if (!str || !str[0]) { - if (key_name) - nm_log_warn (LOGD_SETTINGS, "%s: ignoring missing number %s", __func__, key_name); - return FALSE; - } - - errno = 0; - tmp = strtol (str, &endptr, 10); - if (errno || (tmp < 0) || (tmp > max_val) || *endptr != 0) { - if (key_name) - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid number %s '%s'", __func__, key_name, str); - return FALSE; - } - - *out = (guint32) tmp; - return TRUE; -} - -static gpointer -build_address (int family, const char *address_str, guint32 plen) -{ - NMIPAddress *addr; - GError *error = NULL; - - g_return_val_if_fail (address_str, NULL); - - addr = nm_ip_address_new (family, address_str, plen, &error); - if (!addr) { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid %s address: %s", __func__, - family == AF_INET ? "IPv4" : "IPv6", - error->message); - g_error_free (error); - } - - return addr; -} - -static gpointer -build_route (int family, - const char *dest_str, guint32 plen, - const char *gateway_str, const char *metric_str, - const char *key_name) -{ - NMIPRoute *route; - guint32 metric = 0; - GError *error = NULL; - - g_return_val_if_fail (plen, NULL); - g_return_val_if_fail (dest_str, NULL); - - /* Next hop */ - if (gateway_str && gateway_str[0]) { - if (!nm_utils_ipaddr_valid (family, gateway_str)) { - /* Try workaround for routes written by broken keyfile writer. - * Due to bug bgo#719851, an older version of writer would have - * written "a:b:c:d::/plen,metric" if the gateway was ::, instead - * of "a:b:c:d::/plen,,metric" or "a:b:c:d::/plen,::,metric" - * Try workaround by interpreting gateway_str as metric to accept such - * invalid routes. This broken syntax should not be not officially - * supported. - **/ - if ( family == AF_INET6 - && !metric_str - && get_one_int (gateway_str, G_MAXUINT32, NULL, &metric)) - gateway_str = NULL; - else { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid gateway '%s'", __func__, gateway_str); - return NULL; - } - } - } else - gateway_str = NULL; - - /* parse metric, default to 0 */ - if (metric_str) { - if (!get_one_int (metric_str, G_MAXUINT32, key_name, &metric)) - return NULL; - } - - route = nm_ip_route_new (family, dest_str, plen, gateway_str, - metric ? (gint64) metric : -1, - &error); - if (!route) { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid %s route: %s", __func__, - family == AF_INET ? "IPv4" : "IPv6", - error->message); - g_error_free (error); - } - - return route; -} - -/* On success, returns pointer to the zero-terminated field (original @current). - * The @current * pointer target is set to point to the rest of the input - * or %NULL if there is no more input. Sets error to %NULL for convenience. - * - * On failure, returns %NULL (unspecified). The @current pointer target is - * resets to its original value to allow skipping fields. The @error target - * is set to the character that breaks the parsing or %NULL if @current was %NULL. - * - * When @current target is %NULL, gracefully fail returning %NULL while - * leaving the @current target %NULL end setting @error to %NULL; - */ -static char * -read_field (char **current, char **error, const char *characters, const char *delimiters) -{ - char *start; - - g_return_val_if_fail (current, NULL); - g_return_val_if_fail (error, NULL); - g_return_val_if_fail (characters, NULL); - g_return_val_if_fail (delimiters, NULL); - - *error = NULL; - - if (!*current) { - /* graceful failure, leave '*current' NULL */ - return NULL; - } - - /* fail on empty input */ - if (!**current) - return NULL; - - /* remember beginning of input */ - start = *current; - - while (**current && strchr (characters, **current)) - (*current)++; - if (**current) - if (strchr (delimiters, **current)) { - /* success, more data available */ - *(*current)++ = '\0'; - return start; - } else { - /* error, bad character */ - *error = *current; - *current = start; - return NULL; - } - else { - /* success, end of input */ - *current = NULL; - return start; - } -} - -#define IP_ADDRESS_CHARS "0123456789abcdefABCDEF:.%" -#define DIGITS "0123456789" -#define DELIMITERS "/;," - - -/* The following IPv4 and IPv6 address formats are supported: - * - * address (DEPRECATED) - * address/plen - * address/gateway (DEPRECATED) - * address/plen,gateway - * - * The following IPv4 and IPv6 route formats are supported: - * - * address/plen (NETWORK dev DEVICE) - * address/plen,gateway (NETWORK via GATEWAY dev DEVICE) - * address/plen,,metric (NETWORK dev DEVICE metric METRIC) - * address/plen,gateway,metric (NETWORK via GATEWAY dev DEVICE metric METRIC) - * - * For backward, forward and sideward compatibility, slash (/), - * semicolon (;) and comma (,) are interchangable. The choice of - * separator in the above examples is therefore not significant. - * - * Leaving out the prefix length is discouraged and DEPRECATED. The - * default value of IPv6 prefix length was 64 and has not been - * changed. The default for IPv4 is now 24, which is the closest - * IPv4 equivalent. These defaults may just as well be changed to - * match the iproute2 defaults (32 for IPv4 and 128 for IPv6). - */ -static gpointer -read_one_ip_address_or_route (GKeyFile *file, - const char *setting_name, - const char *key_name, - gboolean ipv6, - gboolean route, - char **out_gateway) -{ - guint32 plen = G_MAXUINT32; - gpointer result; - char *address_str, *plen_str, *gateway_str, *metric_str, *value, *current, *error; - - current = value = nm_keyfile_plugin_kf_get_string (file, setting_name, key_name, NULL); - if (!value) - return NULL; - - /* get address field */ - address_str = read_field (¤t, &error, IP_ADDRESS_CHARS, DELIMITERS); - if (error) { - nm_log_warn (LOGD_SETTINGS, "keyfile: Unexpected character '%c' in '%s.%s' address (position %td of '%s').", - *error, setting_name, key_name, error - current, current); - goto error; - } - /* get prefix length field (skippable) */ - plen_str = read_field (¤t, &error, DIGITS, DELIMITERS); - /* get gateway field */ - gateway_str = read_field (¤t, &error, IP_ADDRESS_CHARS, DELIMITERS); - if (error) { - nm_log_warn (LOGD_SETTINGS, "keyfile: Unexpected character '%c' in '%s.%s' %s (position %td of '%s').", - *error, setting_name, key_name, - plen_str ? "gateway" : "gateway or prefix length", - error - current, current); - goto error; - } - /* for routes, get metric */ - if (route) { - metric_str = read_field (¤t, &error, DIGITS, DELIMITERS); - if (error) { - nm_log_warn (LOGD_SETTINGS, "keyfile: Unexpected character '%c' in '%s.%s' prefix length (position %td of '%s').", - *error, setting_name, key_name, error - current, current); - goto error; - } - } else - metric_str = NULL; - if (current) { - /* there is still some data */ - if (*current) { - /* another field follows */ - nm_log_warn (LOGD_SETTINGS, "keyfile: %s.%s: Garbage at the and of the line: %s", - setting_name, key_name, current); - goto error; - } else { - /* semicolon at the end of input */ - nm_log_info (LOGD_SETTINGS, "keyfile: %s.%s: Deprecated semicolon at the end of value.", - setting_name, key_name); - } - } - -#define DEFAULT_PREFIX(for_route, for_ipv6) ( (for_route) ? ( (for_ipv6) ? 128 : 24 ) : ( (for_ipv6) ? 64 : 24 ) ) - - /* parse plen, fallback to defaults */ - if (plen_str) { - if (!get_one_int (plen_str, ipv6 ? 128 : 32, key_name, &plen) - || (route && plen == 0)) { - plen = DEFAULT_PREFIX (route, ipv6); - nm_log_warn (LOGD_SETTINGS, "keyfile: invalid prefix length '%s' in '%s.%s', defaulting to %d", - plen_str, setting_name, key_name, plen); - } - } else { - plen = DEFAULT_PREFIX (route, ipv6); - nm_log_warn (LOGD_SETTINGS, "keyfile: Missing prefix length in '%s.%s', defaulting to %d", - setting_name, key_name, plen); - } - - /* build the appropriate data structure for NetworkManager settings */ - if (route) { - result = build_route (ipv6 ? AF_INET6 : AF_INET, - address_str, plen, gateway_str, metric_str, - key_name); - } else { - result = build_address (ipv6 ? AF_INET6 : AF_INET, - address_str, plen); - if (out_gateway && gateway_str) - *out_gateway = g_strdup (gateway_str); - } - g_free (value); - return result; -error: - g_free (value); - return NULL; -} +#include "nm-logging.h" +#include "nm-keyfile-internal.h" -static void -ip_address_or_route_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +static const char * +_fmt_warn (const char *group, NMSetting *setting, const char *property_name, const char *message, char **out_message) { - const char *setting_name = nm_setting_get_name (setting); - gboolean ipv6 = !strcmp (setting_name, "ipv6"); - gboolean routes = !strcmp (key, "routes"); - static const char *key_names_routes[] = { "route", "routes", NULL }; - static const char *key_names_addresses[] = { "address", "addresses", NULL }; - const char **key_names = routes ? key_names_routes : key_names_addresses; - char *gateway = NULL; - GPtrArray *list; - GDestroyNotify free_func; - int i; - - if (routes) - free_func = (GDestroyNotify) nm_ip_route_unref; - else - free_func = (GDestroyNotify) nm_ip_address_unref; - list = g_ptr_array_new_with_free_func (free_func); + const char *setting_name = setting ? nm_setting_get_name (setting) : NULL; - for (i = -1; i < 1000; i++) { - const char **key_basename; - - for (key_basename = key_names; *key_basename; key_basename++) { - char *key_name; - gpointer item; + if (group) { + char *res; - /* -1 means no suffix */ - if (i >= 0) - key_name = g_strdup_printf ("%s%d", *key_basename, i); + if (setting_name) { + if (property_name && !strcmp (group, setting_name)) + res = g_strdup_printf ("%s.%s: %s", group, property_name, message); + else if (property_name) + res = g_strdup_printf ("%s/%s.%s: %s", group, setting_name, property_name, message); + else if (!strcmp (group, setting_name)) + res = g_strdup_printf ("%s: %s", group, message); else - key_name = g_strdup (*key_basename); - - item = read_one_ip_address_or_route (keyfile, setting_name, key_name, ipv6, routes, - gateway ? NULL : &gateway); - if (item) - g_ptr_array_add (list, item); - - g_free (key_name); - } - } - - if (list->len >= 1) - g_object_set (setting, key, list, NULL); - - if (gateway) { - g_object_set (setting, "gateway", gateway, NULL); - g_free (gateway); - } - - g_ptr_array_unref (list); -} - -static void -ip4_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) -{ - const char *setting_name = nm_setting_get_name (setting); - GPtrArray *array; - gsize length; - char **list, **iter; - int ret; - - list = nm_keyfile_plugin_kf_get_string_list (keyfile, setting_name, key, &length, NULL); - if (!list || !g_strv_length (list)) - return; - - array = g_ptr_array_sized_new (length + 1); - for (iter = list; *iter; iter++) { - guint32 addr; - - ret = inet_pton (AF_INET, *iter, &addr); - if (ret <= 0) { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid DNS server address '%s'", __func__, *iter); - continue; - } - - g_ptr_array_add (array, *iter); - } - g_ptr_array_add (array, NULL); - - g_object_set (setting, key, array->pdata, NULL); - g_ptr_array_unref (array); - g_strfreev (list); -} - -static void -ip6_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) -{ - const char *setting_name = nm_setting_get_name (setting); - GPtrArray *array = NULL; - gsize length; - char **list, **iter; - int ret; - - list = nm_keyfile_plugin_kf_get_string_list (keyfile, setting_name, key, &length, NULL); - if (!list || !g_strv_length (list)) - return; - - array = g_ptr_array_sized_new (length + 1); - - for (iter = list; *iter; iter++) { - struct in6_addr addr; - - ret = inet_pton (AF_INET6, *iter, &addr); - if (ret <= 0) { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid DNS server IPv6 address '%s'", __func__, *iter); - continue; - } - - g_ptr_array_add (array, *iter); - } - g_ptr_array_add (array, NULL); - - g_object_set (setting, key, array->pdata, NULL); - g_ptr_array_unref (array); - g_strfreev (list); -} - -static void -mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path, gsize enforce_length) -{ - const char *setting_name = nm_setting_get_name (setting); - char *tmp_string = NULL, *p, *mac_str; - gint *tmp_list; - GByteArray *array = NULL; - gsize length; - - p = tmp_string = nm_keyfile_plugin_kf_get_string (keyfile, setting_name, key, NULL); - if (tmp_string && tmp_string[0]) { - /* Look for enough ':' characters to signify a MAC address */ - guint i = 0; - - while (*p) { - if (*p == ':') - i++; - p++; - } - - if (enforce_length == 0 || enforce_length == i+1) { - /* If we found enough it's probably a string-format MAC address */ - array = g_byte_array_sized_new (i+1); - g_byte_array_set_size (array, i+1); - if (!nm_utils_hwaddr_aton (tmp_string, array->data, array->len)) { - g_byte_array_unref (array); - array = NULL; - } - } - } - g_free (tmp_string); - - if (array == NULL) { - /* Old format; list of ints */ - tmp_list = nm_keyfile_plugin_kf_get_integer_list (keyfile, setting_name, key, &length, NULL); - if (length > 0 && (enforce_length == 0 || enforce_length == length)) { - gsize i; - - array = g_byte_array_sized_new (length); - for (i = 0; i < length; i++) { - int val = tmp_list[i]; - const guint8 v = (guint8) (val & 0xFF); - - if (val < 0 || val > 255) { - nm_log_warn (LOGD_SETTINGS, "%s: %s / %s ignoring invalid byte element '%d' (not " - " between 0 and 255 inclusive)", __func__, setting_name, - key, val); - g_byte_array_free (array, TRUE); - array = NULL; - break; - } - g_byte_array_append (array, &v, 1); - } - } - g_free (tmp_list); - } - - if (!array) { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid MAC address for %s / %s", - __func__, setting_name, key); - return; - } - - mac_str = nm_utils_hwaddr_ntoa (array->data, array->len); - g_object_set (setting, key, mac_str, NULL); - g_free (mac_str); - g_byte_array_free (array, TRUE); -} - -static void -mac_address_parser_ETHER (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) -{ - mac_address_parser (setting, key, keyfile, keyfile_path, ETH_ALEN); -} - -static void -mac_address_parser_INFINIBAND (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) -{ - mac_address_parser (setting, key, keyfile, keyfile_path, INFINIBAND_ALEN); -} - -static void -read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key) -{ - char **keys, **iter; - char *value; - const char *setting_name = nm_setting_get_name (setting); - - keys = nm_keyfile_plugin_kf_get_keys (file, setting_name, NULL, NULL); - if (!keys || !*keys) - return; - - for (iter = keys; *iter; iter++) { - value = nm_keyfile_plugin_kf_get_string (file, setting_name, *iter, NULL); - if (!value) - continue; - - if (NM_IS_SETTING_VPN (setting)) { - /* Add any item that's not a class property to the data hash */ - if (!g_object_class_find_property (G_OBJECT_GET_CLASS (setting), *iter)) - nm_setting_vpn_add_data_item (NM_SETTING_VPN (setting), *iter, value); - } - if (NM_IS_SETTING_BOND (setting)) { - if (strcmp (*iter, "interface-name")) - nm_setting_bond_add_option (NM_SETTING_BOND (setting), *iter, value); - } - g_free (value); - } - g_strfreev (keys); -} - -static void -unescape_semicolons (char *str) -{ - int i; - gsize len = strlen (str); - - for (i = 0; i < len; i++) { - if (str[i] == '\\' && str[i+1] == ';') { - memmove(str + i, str + i + 1, len - (i + 1)); - len--; - } - str[len] = '\0'; - } -} - -static GBytes * -get_bytes (GKeyFile *keyfile, - const char *setting_name, - const char *key, - gboolean zero_terminate, - gboolean unescape_semicolon) -{ - GByteArray *array = NULL; - char *tmp_string; - gint *tmp_list; - gsize length; - int i; - - /* New format: just a string - * Old format: integer list; e.g. 11;25;38; - */ - tmp_string = nm_keyfile_plugin_kf_get_string (keyfile, setting_name, key, NULL); - if (tmp_string) { - GRegex *regex; - GMatchInfo *match_info; - const char *pattern = "^[[:space:]]*[[:digit:]]{1,3}[[:space:]]*;([[:space:]]*[[:digit:]]{1,3}[[:space:]]*;)*([[:space:]]*)?$"; - - regex = g_regex_new (pattern, 0, 0, NULL); - g_regex_match (regex, tmp_string, 0, &match_info); - if (!g_match_info_matches (match_info)) { - /* Handle as a simple string (ie, new format) */ - if (unescape_semicolon) - unescape_semicolons (tmp_string); - length = strlen (tmp_string); - if (zero_terminate) - length++; - array = g_byte_array_sized_new (length); - g_byte_array_append (array, (guint8 *) tmp_string, length); - } - g_match_info_free (match_info); - g_regex_unref (regex); - g_free (tmp_string); - } - - if (!array) { - /* Old format; list of ints */ - tmp_list = nm_keyfile_plugin_kf_get_integer_list (keyfile, setting_name, key, &length, NULL); - array = g_byte_array_sized_new (length); - for (i = 0; i < length; i++) { - int val = tmp_list[i]; - unsigned char v = (unsigned char) (val & 0xFF); - - if (val < 0 || val > 255) { - nm_log_warn (LOGD_SETTINGS, "%s: %s / %s ignoring invalid byte element '%d' (not " - " between 0 and 255 inclusive)", __func__, setting_name, - key, val); - } else - g_byte_array_append (array, (const unsigned char *) &v, sizeof (v)); - } - g_free (tmp_list); - } - - if (array->len == 0) { - g_byte_array_free (array, TRUE); - return NULL; + res = g_strdup_printf ("%s/%s: %s", group, setting_name, message); + } else + res = g_strdup_printf ("%s: %s", group, message); + *out_message = res; + return res; } else - return g_byte_array_free_to_bytes (array); -} - -static void -ssid_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) -{ - const char *setting_name = nm_setting_get_name (setting); - GBytes *bytes; - - bytes = get_bytes (keyfile, setting_name, key, FALSE, TRUE); - if (bytes) { - g_object_set (setting, key, bytes, NULL); - g_bytes_unref (bytes); - } else { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid SSID for %s / %s", - __func__, setting_name, key); - } -} - -static void -password_raw_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) -{ - const char *setting_name = nm_setting_get_name (setting); - GBytes *bytes; - - bytes = get_bytes (keyfile, setting_name, key, FALSE, TRUE); - if (bytes) { - g_object_set (setting, key, bytes, NULL); - g_bytes_unref (bytes); - } else { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid raw password for %s / %s", - __func__, setting_name, key); - } -} - -static char * -get_cert_path (const char *keyfile_path, const guint8 *cert_path, gsize cert_path_len) -{ - const char *base; - char *p = NULL, *path, *dirname, *tmp; - - g_return_val_if_fail (keyfile_path != NULL, NULL); - g_return_val_if_fail (cert_path != NULL, NULL); - - base = path = g_malloc0 (cert_path_len + 1); - memcpy (path, cert_path, cert_path_len); - - if (path[0] == '/') - return path; - - p = strrchr (path, '/'); - if (p) - base = p + 1; - - dirname = g_path_get_dirname (keyfile_path); - tmp = g_build_path ("/", dirname, base, NULL); - g_free (dirname); - g_free (path); - return tmp; + return message; } -#define SCHEME_PATH "file://" - -static const char *certext[] = { ".pem", ".cert", ".crt", ".cer", ".p12", ".der", ".key" }; - static gboolean -has_cert_ext (const char *path) -{ - int i; - - for (i = 0; i < G_N_ELEMENTS (certext); i++) { - if (g_str_has_suffix (path, certext[i])) - return TRUE; - } - return FALSE; -} - -static gboolean -handle_as_scheme (GBytes *bytes, NMSetting *setting, const char *key) -{ - const guint8 *data; - gsize data_len; - - data = g_bytes_get_data (bytes, &data_len); +_handler_read (GKeyFile *keyfile, + NMConnection *connection, + NMKeyfileReadType type, + void *type_data, + void *user_data, + GError **error) +{ + if (type == NM_KEYFILE_READ_TYPE_WARN) { + NMKeyfileReadTypeDataWarn *warn_data = type_data; + NMLogLevel level; + char *message_free = NULL; + + if (warn_data->severity > NM_KEYFILE_WARN_SEVERITY_WARN) + level = LOGL_ERR; + else if (warn_data->severity >= NM_KEYFILE_WARN_SEVERITY_WARN) + level = LOGL_WARN; + else if (warn_data->severity == NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE) + level = LOGL_WARN; + else + level = LOGL_INFO; - /* It's the PATH scheme, can just set plain data */ - if ( (data_len > strlen (SCHEME_PATH)) - && g_str_has_prefix ((const char *) data, SCHEME_PATH) - && (data[data_len - 1] == '\0')) { - g_object_set (setting, key, bytes, NULL); + nm_log (level, LOGD_SETTINGS, "keyfile: %s", + _fmt_warn (warn_data->group, warn_data->setting, + warn_data->property_name, warn_data->message, + &message_free)); + g_free (message_free); return TRUE; } return FALSE; } -static gboolean -handle_as_path (GBytes *bytes, - NMSetting *setting, - const char *key, - const char *keyfile_path) -{ - const guint8 *data; - gsize data_len; - gsize validate_len; - char *path; - gboolean exists, success = FALSE; - - data = g_bytes_get_data (bytes, &data_len); - if (data_len > 500 || data_len < 1) - return FALSE; - - /* If there's a trailing NULL tell g_utf8_validate() to to until the NULL */ - if (data[data_len - 1] == '\0') - validate_len = -1; - else - validate_len = data_len; - - if (g_utf8_validate ((const char *) data, validate_len, NULL) == FALSE) - return FALSE; - - /* Might be a bare path without the file:// prefix; in that case - * if it's an absolute path, use that, otherwise treat it as a - * relative path to the current directory. - */ - - path = get_cert_path (keyfile_path, data, data_len); - exists = g_file_test (path, G_FILE_TEST_EXISTS); - if ( exists - || memchr (data, '/', data_len) - || has_cert_ext (path)) { - GByteArray *tmp; - GBytes *val; - - /* Construct the proper value as required for the PATH scheme */ - tmp = g_byte_array_sized_new (strlen (SCHEME_PATH) + strlen (path) + 1); - g_byte_array_append (tmp, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); - g_byte_array_append (tmp, (const guint8 *) path, strlen (path)); - g_byte_array_append (tmp, (const guint8 *) "\0", 1); - val = g_byte_array_free_to_bytes (tmp); - g_object_set (setting, key, val, NULL); - g_bytes_unref (val); - success = TRUE; - - /* Warn if the certificate didn't exist */ - if (exists == FALSE) - nm_log_warn (LOGD_SETTINGS, "certificate or key %s does not exist", path); - } - g_free (path); - - return success; -} - -static void -cert_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) -{ - const char *setting_name = nm_setting_get_name (setting); - GBytes *bytes; - gboolean success = FALSE; - - bytes = get_bytes (keyfile, setting_name, key, TRUE, FALSE); - if (bytes) { - /* Try as a path + scheme (ie, starts with "file://") */ - success = handle_as_scheme (bytes, setting, key); - - /* If not, it might be a plain path */ - if (success == FALSE) - success = handle_as_path (bytes, setting, key, keyfile_path); - - /* If neither of those two, assume blob with certificate data */ - if (success == FALSE) - g_object_set (setting, key, bytes, NULL); - } else { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid key/cert value for %s / %s", - __func__, setting_name, key); - } - - if (bytes) - g_bytes_unref (bytes); -} - -static void -parity_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) -{ - const char *setting_name = nm_setting_get_name (setting); - NMSettingSerialParity parity; - int int_val; - char *str_val; - - /* Keyfile traditionally stored this as the ASCII value for 'E', 'o', or 'n'. - * We now accept either that or the (case-insensitive) character itself (but - * still always write it the old way, for backward compatibility). - */ - int_val = nm_keyfile_plugin_kf_get_integer (keyfile, setting_name, key, NULL); - if (!int_val) { - str_val = nm_keyfile_plugin_kf_get_string (keyfile, setting_name, key, NULL); - if (str_val) { - if (str_val[0] && !str_val[1]) - int_val = str_val[0]; - else { - /* This will hit the warning below */ - int_val = 'X'; - } - } - g_free (str_val); - } - - if (!int_val) - return; - - switch (int_val) { - case 'E': - case 'e': - parity = NM_SETTING_SERIAL_PARITY_EVEN; - break; - case 'O': - case 'o': - parity = NM_SETTING_SERIAL_PARITY_ODD; - break; - case 'N': - case 'n': - parity = NM_SETTING_SERIAL_PARITY_NONE; - break; - default: - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid value for %s / %s", - __func__, setting_name, key); - return; - } - - g_object_set (setting, key, parity, NULL); -} - -typedef struct { - const char *setting_name; - const char *key; - gboolean check_for_key; - void (*parser) (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path); -} KeyParser; - -/* A table of keys that require further parsing/conversion because they are - * stored in a format that can't be automatically read using the key's type. - * i.e. IPv4 addresses, which are stored in NetworkManager as guint32, but are - * stored in keyfiles as strings, eg "10.1.1.2" or IPv6 addresses stored - * in struct in6_addr internally, but as string in keyfiles. - */ -static KeyParser key_parsers[] = { - { NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_TYPE, - TRUE, - setting_alias_parser }, - { NM_SETTING_BRIDGE_SETTING_NAME, - NM_SETTING_BRIDGE_MAC_ADDRESS, - TRUE, - mac_address_parser_ETHER }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_ADDRESSES, - FALSE, - ip_address_or_route_parser }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_ADDRESSES, - FALSE, - ip_address_or_route_parser }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_ROUTES, - FALSE, - ip_address_or_route_parser }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_ROUTES, - FALSE, - ip_address_or_route_parser }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_DNS, - FALSE, - ip4_dns_parser }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_DNS, - FALSE, - ip6_dns_parser }, - { NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MAC_ADDRESS, - TRUE, - mac_address_parser_ETHER }, - { NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_CLONED_MAC_ADDRESS, - TRUE, - mac_address_parser_ETHER }, - { NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_MAC_ADDRESS, - TRUE, - mac_address_parser_ETHER }, - { NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, - TRUE, - mac_address_parser_ETHER }, - { NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_BSSID, - TRUE, - mac_address_parser_ETHER }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, - NM_SETTING_BLUETOOTH_BDADDR, - TRUE, - mac_address_parser_ETHER }, - { NM_SETTING_INFINIBAND_SETTING_NAME, - NM_SETTING_INFINIBAND_MAC_ADDRESS, - TRUE, - mac_address_parser_INFINIBAND }, - { NM_SETTING_WIMAX_SETTING_NAME, - NM_SETTING_WIMAX_MAC_ADDRESS, - TRUE, - mac_address_parser_ETHER }, - { NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_SSID, - TRUE, - ssid_parser }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_PASSWORD_RAW, - TRUE, - password_raw_parser }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_CA_CERT, - TRUE, - cert_parser }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_CLIENT_CERT, - TRUE, - cert_parser }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_PRIVATE_KEY, - TRUE, - cert_parser }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_PHASE2_CA_CERT, - TRUE, - cert_parser }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_PHASE2_CLIENT_CERT, - TRUE, - cert_parser }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, - TRUE, - cert_parser }, - { NM_SETTING_SERIAL_SETTING_NAME, - NM_SETTING_SERIAL_PARITY, - TRUE, - parity_parser }, - { NULL, NULL, FALSE } -}; - -typedef struct { - GKeyFile *keyfile; - const char *keyfile_path; -} ReadInfo; - -static void -read_one_setting_value (NMSetting *setting, - const char *key, - const GValue *value, - GParamFlags flags, - gpointer user_data) -{ - ReadInfo *info = user_data; - const char *setting_name; - int errsv; - GType type; - GError *err = NULL; - gboolean check_for_key = TRUE; - KeyParser *parser = &key_parsers[0]; - - /* Property is not writable */ - if (!(flags & G_PARAM_WRITABLE)) - return; - - /* Setting name gets picked up from the keyfile's section name instead */ - if (!strcmp (key, NM_SETTING_NAME)) - return; - - /* Don't read the NMSettingConnection object's 'read-only' property */ - if ( NM_IS_SETTING_CONNECTION (setting) - && !strcmp (key, NM_SETTING_CONNECTION_READ_ONLY)) - return; - - setting_name = nm_setting_get_name (setting); - - /* Look through the list of handlers for non-standard format key values */ - while (parser->setting_name) { - if (!strcmp (parser->setting_name, setting_name) && !strcmp (parser->key, key)) { - check_for_key = parser->check_for_key; - break; - } - parser++; - } - - /* VPN properties don't have the exact key name */ - if (NM_IS_SETTING_VPN (setting)) - check_for_key = FALSE; - - /* Bonding 'options' don't have the exact key name. The options are right under [bond] group. */ - if (NM_IS_SETTING_BOND (setting)) - check_for_key = FALSE; - - /* Check for the exact key in the GKeyFile if required. Most setting - * properties map 1:1 to a key in the GKeyFile, but for those properties - * like IP addresses and routes where more than one value is actually - * encoded by the setting property, this won't be true. - */ - if (check_for_key && !nm_keyfile_plugin_kf_has_key (info->keyfile, setting_name, key, &err)) { - /* Key doesn't exist or an error ocurred, thus nothing to do. */ - if (err) { - nm_log_warn (LOGD_SETTINGS, "Error loading setting '%s' value: %s", setting_name, err->message); - g_error_free (err); - } - return; - } - - /* If there's a custom parser for this key, handle that before the generic - * parsers below. - */ - if (parser->setting_name) { - (*parser->parser) (setting, key, info->keyfile, info->keyfile_path); - return; - } - - type = G_VALUE_TYPE (value); - - if (type == G_TYPE_STRING) { - char *str_val; - - str_val = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL); - g_object_set (setting, key, str_val, NULL); - g_free (str_val); - } else if (type == G_TYPE_UINT) { - int int_val; - - int_val = nm_keyfile_plugin_kf_get_integer (info->keyfile, setting_name, key, NULL); - if (int_val < 0) - nm_log_warn (LOGD_SETTINGS, "Casting negative value (%i) to uint", int_val); - g_object_set (setting, key, int_val, NULL); - } else if (type == G_TYPE_INT) { - int int_val; - - int_val = nm_keyfile_plugin_kf_get_integer (info->keyfile, setting_name, key, NULL); - g_object_set (setting, key, int_val, NULL); - } else if (type == G_TYPE_BOOLEAN) { - gboolean bool_val; - - bool_val = nm_keyfile_plugin_kf_get_boolean (info->keyfile, setting_name, key, NULL); - g_object_set (setting, key, bool_val, NULL); - } else if (type == G_TYPE_CHAR) { - int int_val; - - int_val = nm_keyfile_plugin_kf_get_integer (info->keyfile, setting_name, key, NULL); - if (int_val < G_MININT8 || int_val > G_MAXINT8) - nm_log_warn (LOGD_SETTINGS, "Casting value (%i) to char", int_val); - - g_object_set (setting, key, int_val, NULL); - } else if (type == G_TYPE_UINT64) { - char *tmp_str; - guint64 uint_val; - - tmp_str = nm_keyfile_plugin_kf_get_value (info->keyfile, setting_name, key, NULL); - uint_val = g_ascii_strtoull (tmp_str, NULL, 10); - g_free (tmp_str); - g_object_set (setting, key, uint_val, NULL); - } else if (type == G_TYPE_INT64) { - char *tmp_str; - gint64 int_val; - - tmp_str = nm_keyfile_plugin_kf_get_value (info->keyfile, setting_name, key, NULL); - int_val = nm_utils_ascii_str_to_int64 (tmp_str, 10, G_MININT64, G_MAXINT64, 0); - errsv = errno; - if (errsv) - nm_log_warn (LOGD_SETTINGS, "Invalid int64 value (%s)", tmp_str); - else - g_object_set (setting, key, int_val, NULL); - g_free (tmp_str); - } else if (type == G_TYPE_BYTES) { - gint *tmp; - GByteArray *array; - GBytes *bytes; - gsize length; - int i; - - tmp = nm_keyfile_plugin_kf_get_integer_list (info->keyfile, setting_name, key, &length, NULL); - - array = g_byte_array_sized_new (length); - for (i = 0; i < length; i++) { - int val = tmp[i]; - unsigned char v = (unsigned char) (val & 0xFF); - - if (val < 0 || val > 255) { - nm_log_warn (LOGD_SETTINGS, "%s: %s / %s ignoring invalid byte element '%d' (not " - " between 0 and 255 inclusive)", __func__, setting_name, - key, val); - } else - g_byte_array_append (array, (const unsigned char *) &v, sizeof (v)); - } - - bytes = g_byte_array_free_to_bytes (array); - g_object_set (setting, key, bytes, NULL); - g_bytes_unref (bytes); - g_free (tmp); - } else if (type == G_TYPE_STRV) { - gchar **sa; - gsize length; - - sa = nm_keyfile_plugin_kf_get_string_list (info->keyfile, setting_name, key, &length, NULL); - g_object_set (setting, key, sa, NULL); - g_strfreev (sa); - } else if (type == G_TYPE_HASH_TABLE) { - read_hash_of_string (info->keyfile, setting, key); - } else if (type == G_TYPE_ARRAY) { - if (!read_array_of_uint (info->keyfile, setting, key)) { - nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (read): '%s/%s' : '%s'", - setting_name, key, G_VALUE_TYPE_NAME (value)); - } - } else if (G_VALUE_HOLDS_FLAGS (value)) { - guint64 uint_val; - - /* Flags are guint but GKeyFile has no uint reader, just uint64 */ - uint_val = nm_keyfile_plugin_kf_get_uint64 (info->keyfile, setting_name, key, &err); - if (!err) { - if (uint_val <= G_MAXUINT) - g_object_set (setting, key, (guint) uint_val, NULL); - else { - nm_log_warn (LOGD_SETTINGS, "Too large FLAGS property (read): '%s/%s' : '%s'", - setting_name, key, G_VALUE_TYPE_NAME (value)); - } - } - g_clear_error (&err); - } else if (G_VALUE_HOLDS_ENUM (value)) { - gint int_val; - - int_val = nm_keyfile_plugin_kf_get_integer (info->keyfile, setting_name, key, &err); - if (!err) - g_object_set (setting, key, (gint) int_val, NULL); - g_clear_error (&err); - } else { - nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (read): '%s/%s' : '%s'", - setting_name, key, G_VALUE_TYPE_NAME (value)); - } -} - -static NMSetting * -read_setting (GKeyFile *file, const char *keyfile_path, const char *group) -{ - NMSetting *setting = NULL; - ReadInfo info = { file, keyfile_path }; - const char *alias; - GType type; - - alias = nm_keyfile_plugin_get_setting_name_for_alias (group); - if (alias) - group = alias; - - type = nm_setting_lookup_type (group); - if (type) { - setting = g_object_new (type, NULL); - nm_setting_enumerate_values (setting, read_one_setting_value, &info); - } else - nm_log_warn (LOGD_SETTINGS, "Invalid setting name '%s'", group); - - return setting; -} - -static void -read_vpn_secrets (GKeyFile *file, NMSettingVpn *s_vpn) -{ - char **keys, **iter; - - keys = nm_keyfile_plugin_kf_get_keys (file, VPN_SECRETS_GROUP, NULL, NULL); - for (iter = keys; *iter; iter++) { - char *secret; - - secret = nm_keyfile_plugin_kf_get_string (file, VPN_SECRETS_GROUP, *iter, NULL); - if (secret) { - nm_setting_vpn_add_secret (s_vpn, *iter, secret); - g_free (secret); - } - } - g_strfreev (keys); -} - NMConnection * nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) { @@ -1255,12 +92,6 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) struct stat statbuf; gboolean bad_permissions; NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSetting *setting; - gchar **groups; - gsize length; - int i; - gboolean vpn_secrets = FALSE; GError *verify_error = NULL; if (stat (filename, &statbuf) != 0 || !S_ISREG (statbuf.st_mode)) { @@ -1282,77 +113,14 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, error)) goto out; - connection = nm_simple_connection_new (); - - groups = g_key_file_get_groups (key_file, &length); - for (i = 0; i < length; i++) { - /* Only read out secrets when needed */ - if (!strcmp (groups[i], VPN_SECRETS_GROUP)) { - vpn_secrets = TRUE; - continue; - } - - setting = read_setting (key_file, filename, groups[i]); - if (setting) - nm_connection_add_setting (connection, setting); - } - - s_con = nm_connection_get_setting_connection (connection); - if (!s_con) { - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - } - - /* Make sure that we have 'id' even if not explictly specified in the keyfile */ - if (!nm_setting_connection_get_id (s_con)) { - char *base_name; - - base_name = g_path_get_basename (filename); - g_object_set (s_con, NM_SETTING_CONNECTION_ID, base_name, NULL); - g_free (base_name); - } - - /* Make sure that we have 'uuid' even if not explictly specified in the keyfile */ - if (!nm_setting_connection_get_uuid (s_con)) { - char *hashed_uuid; - - hashed_uuid = nm_utils_uuid_generate_from_strings ("keyfile", filename, NULL); - g_object_set (s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL); - g_free (hashed_uuid); - } - - /* Make sure that we have 'interface-name' even if it was specified in the - * "wrong" (ie, deprecated) group. - */ - if ( !nm_setting_connection_get_interface_name (s_con) - && nm_setting_connection_get_connection_type (s_con)) { - char *interface_name; - - interface_name = g_key_file_get_string (key_file, - nm_setting_connection_get_connection_type (s_con), - "interface-name", - NULL); - if (interface_name) { - g_object_set (s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, interface_name, NULL); - g_free (interface_name); - } - } - - /* Handle vpn secrets after the 'vpn' setting was read */ - if (vpn_secrets) { - NMSettingVpn *s_vpn; - - s_vpn = nm_connection_get_setting_vpn (connection); - if (s_vpn) - read_vpn_secrets (key_file, s_vpn); - } - - g_strfreev (groups); + connection = nm_keyfile_read (key_file, filename, NULL, _handler_read, NULL, error); + if (!connection) + goto out; /* Normalize and verify the connection */ if (!nm_connection_normalize (connection, NULL, NULL, &verify_error)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "invalid connection: %s", + "invalid connection: %s", verify_error->message); g_clear_error (&verify_error); g_object_unref (connection); @@ -1363,3 +131,4 @@ out: g_key_file_free (key_file); return connection; } + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Blob b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Blob index 9f4ef62fd4..62e6ae31fd 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Blob +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Blob @@ -8,8 +8,8 @@ type=802-3-ethernet eap=tls; identity=Bill Smith ca-cert=48;130;2;52;48;130;1;161;2;16;2;173;102;126;78;69;254;94;87;111;60;152;25;94;221;192;48;13;6;9;42;134;72;134;247;13;1;1;2;5;0;48;95;49;11;48;9;6;3;85;4;6;19;2;85;83;49;32;48;30;6;3;85;4;10;19;23;82;83;65;32;68;97;116;97;32;83;101;99;117;114;105;116;121;44;32;73;110;99;46;49;46;48;44;6;3;85;4;11;19;37;83;101;99;117;114;101;32;83;101;114;118;101;114;32;67;101;114;116;105;102;105;99;97;116;105;111;110;32;65;117;116;104;111;114;105;116;121;48;30;23;13;57;52;49;49;48;57;48;48;48;48;48;48;90;23;13;49;48;48;49;48;55;50;51;53;57;53;57;90;48;95;49;11;48;9;6;3;85;4;6;19;2;85;83;49;32;48;30;6;3;85;4;10;19;23;82;83;65;32;68;97;116;97;32;83;101;99;117;114;105;116;121;44;32;73;110;99;46;49;46;48;44;6;3;85;4;11;19;37;83;101;99;117;114;101;32;83;101;114;118;101;114;32;67;101;114;116;105;102;105;99;97;116;105;111;110;32;65;117;116;104;111;114;105;116;121;48;129;155;48;13;6;9;42;134;72;134;247;13;1;1;1;5;0;3;129;137;0;48;129;133;2;126;0;146;206;122;193;174;131;62;90;170;137;131;87;172;37;1;118;12;173;174;142;44;55;206;235;53;120;100;84;3;229;132;64;81;201;191;143;8;226;138;130;8;210;22;134;55;85;233;177;33;2;173;118;104;129;154;5;162;75;201;75;37;102;34;86;108;136;7;143;247;129;89;109;132;7;101;112;19;113;118;62;155;119;76;227;80;137;86;152;72;185;29;167;41;26;19;46;74;17;89;156;30;21;213;73;84;44;115;58;105;130;177;151;57;156;109;112;103;72;229;221;45;214;200;30;123;2;3;1;0;1;48;13;6;9;42;134;72;134;247;13;1;1;2;5;0;3;126;0;101;221;126;225;178;236;176;226;58;224;236;113;70;154;25;17;184;211;199;160;180;3;64;38;2;62;9;156;225;18;179;209;90;246;55;165;183;97;3;182;91;22;105;59;198;68;8;12;136;83;12;107;151;73;199;62;53;220;108;185;187;170;223;92;187;58;47;147;96;182;169;75;77;242;32;247;205;95;127;100;123;142;220;0;92;215;250;119;202;57;22;89;111;14;234;211;181;131;127;77;77;66;86;118;180;201;95;4;248;56;248;235;210;95;117;95;205;123;252;229;142;128;124;252;80; -client-cert=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0; -private-key=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0; +client-cert=102;105;108;101;58;47;47;47;67;65;83;65;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0; +private-key=102;105;108;101;58;47;47;47;67;65;83;65;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0; private-key-password=12345testing [ipv4] diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old index 61afdd91c8..d3da598c81 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old @@ -7,9 +7,9 @@ type=802-3-ethernet [802-1x] eap=tls; identity=Bill Smith -ca-cert=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;67;65;47;101;97;112;116;101;115;116;95;99;97;95;99;101;114;116;46;112;101;109;0; -client-cert=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0; -private-key=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0; +ca-cert=102;105;108;101;58;47;47;47;67;65;83;65;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;67;65;47;101;97;112;116;101;115;116;95;99;97;95;99;101;114;116;46;112;101;109;0; +client-cert=102;105;108;101;58;47;47;47;67;65;83;65;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0; +private-key=102;105;108;101;58;47;47;47;67;65;83;65;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0; private-key-password=12345testing [ipv4] diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c index b1de5d3ca1..a86bfed6c2 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile.c @@ -100,33 +100,33 @@ test_read_valid_wired_connection (void) const char *expected6_dnssearch3 = "gnu.org"; g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv4.addresses1*semicolon at the end*"); + "*ipv4.addresses:*semicolon at the end*addresses1*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv4.addresses2*semicolon at the end*"); + "*ipv4.addresses:*semicolon at the end*addresses2*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*Missing prefix length*ipv4.address4*"); + "*missing prefix length*address4*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*Missing prefix length*ipv4.address5*"); + "*missing prefix length*address5*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv4.routes2*semicolon at the end*"); + "*ipv4.routes*semicolon at the end*routes2*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv4.routes3*semicolon at the end*"); + "*ipv4.routes*semicolon at the end*routes3*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv4.routes5*semicolon at the end*"); + "*ipv4.routes*semicolon at the end*routes5*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv4.routes8*semicolon at the end*"); + "*ipv4.routes*semicolon at the end*routes8*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*Missing prefix length*ipv6.address4*"); + "*missing prefix length*address4*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv6.address5*semicolon at the end*"); + "*ipv6.address*semicolon at the end*address5*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*Missing prefix length*ipv6.address5*"); + "*missing prefix length*address5*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv6.address7*semicolon at the end*"); + "*ipv6.address*semicolon at the end*address7*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv6.routes1*semicolon at the end*"); + "*ipv6.routes*semicolon at the end*routes1*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv6.route6*semicolon at the end*"); + "*ipv6.route*semicolon at the end*route6*"); connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_FILE, NULL); g_test_assert_expected_messages (); ASSERT (connection != NULL, @@ -773,11 +773,11 @@ test_read_wired_mac_case (void) const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57"; g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv4.addresses1*semicolon at the end*"); + "*ipv4.addresses*semicolon at the end*addresses1*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv4.addresses2*semicolon at the end*"); + "*ipv4.addresses*semicolon at the end*addresses2*"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, - "*ipv6.routes1*semicolon at the end*"); + "*ipv6.routes*semicolon at the end*routes1*"); connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_MAC_CASE_FILE, NULL); g_test_assert_expected_messages (); ASSERT (connection != NULL, @@ -2127,6 +2127,10 @@ test_read_wired_8021x_tls_blob_connection (void) gboolean success; GBytes *blob; + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*<warn> keyfile: 802-1x.client-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*<warn> keyfile: 802-1x.private-key: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_TLS_BLOB_FILE, &error); if (connection == NULL) { g_assert (error); @@ -2174,10 +2178,10 @@ test_read_wired_8021x_tls_blob_connection (void) g_assert_cmpint (g_bytes_get_size (blob), ==, 568); tmp = nm_setting_802_1x_get_client_cert_path (s_8021x); - g_assert_cmpstr (tmp, ==, "/home/dcbw/Desktop/certinfra/client.pem"); + g_assert_cmpstr (tmp, ==, "/CASA/dcbw/Desktop/certinfra/client.pem"); tmp = nm_setting_802_1x_get_private_key_path (s_8021x); - g_assert_cmpstr (tmp, ==, "/home/dcbw/Desktop/certinfra/client.pem"); + g_assert_cmpstr (tmp, ==, "/CASA/dcbw/Desktop/certinfra/client.pem"); g_object_unref (connection); } @@ -2259,6 +2263,12 @@ test_read_wired_8021x_tls_old_connection (void) const char *tmp; gboolean success; + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*<warn> keyfile: 802-1x.ca-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem' does not exist*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*<warn> keyfile: 802-1x.client-cert: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*<warn> keyfile: 802-1x.private-key: certificate or key file '/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*"); connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_TLS_OLD_FILE, &error); if (connection == NULL) { g_assert (error); @@ -2292,13 +2302,13 @@ test_read_wired_8021x_tls_old_connection (void) g_assert (g_strcmp0 (tmp, "12345testing") == 0); tmp = nm_setting_802_1x_get_ca_cert_path (s_8021x); - g_assert (g_strcmp0 (tmp, "/home/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem") == 0); + g_assert (g_strcmp0 (tmp, "/CASA/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem") == 0); tmp = nm_setting_802_1x_get_client_cert_path (s_8021x); - g_assert (g_strcmp0 (tmp, "/home/dcbw/Desktop/certinfra/client.pem") == 0); + g_assert (g_strcmp0 (tmp, "/CASA/dcbw/Desktop/certinfra/client.pem") == 0); tmp = nm_setting_802_1x_get_private_key_path (s_8021x); - g_assert (g_strcmp0 (tmp, "/home/dcbw/Desktop/certinfra/client.pem") == 0); + g_assert (g_strcmp0 (tmp, "/CASA/dcbw/Desktop/certinfra/client.pem") == 0); g_object_unref (connection); } diff --git a/src/settings/plugins/keyfile/utils.c b/src/settings/plugins/keyfile/utils.c index 30400b1bc4..4809c642c0 100644 --- a/src/settings/plugins/keyfile/utils.c +++ b/src/settings/plugins/keyfile/utils.c @@ -146,178 +146,3 @@ nm_keyfile_plugin_utils_escape_filename (const char *filename) return g_string_free (str, FALSE);; } - -typedef struct { - const char *setting; - const char *alias; -} SettingAlias; - -static const SettingAlias alias_list[] = { - { NM_SETTING_WIRED_SETTING_NAME, "ethernet" }, - { NM_SETTING_WIRELESS_SETTING_NAME, "wifi" }, - { NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, "wifi-security" }, -}; - -const char * -nm_keyfile_plugin_get_alias_for_setting_name (const char *setting_name) -{ - guint i; - - g_return_val_if_fail (setting_name != NULL, NULL); - - for (i = 0; i < G_N_ELEMENTS (alias_list); i++) { - if (strcmp (setting_name, alias_list[i].setting) == 0) - return alias_list[i].alias; - } - return NULL; -} - -const char * -nm_keyfile_plugin_get_setting_name_for_alias (const char *alias) -{ - guint i; - - g_return_val_if_fail (alias != NULL, NULL); - - for (i = 0; i < G_N_ELEMENTS (alias_list); i++) { - if (strcmp (alias, alias_list[i].alias) == 0) - return alias_list[i].setting; - } - return NULL; -} - -/**********************************************************************/ - -/* List helpers */ -#define DEFINE_KF_LIST_WRAPPER(stype, get_ctype, set_ctype) \ -get_ctype \ -nm_keyfile_plugin_kf_get_##stype##_list (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - gsize *out_length, \ - GError **error) \ -{ \ - get_ctype list; \ - const char *alias; \ - GError *local = NULL; \ - \ - list = g_key_file_get_##stype##_list (kf, group, key, out_length, &local); \ - if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { \ - alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ - if (alias) { \ - g_clear_error (&local); \ - list = g_key_file_get_##stype##_list (kf, alias, key, out_length, &local); \ - } \ - } \ - if (local) \ - g_propagate_error (error, local); \ - return list; \ -} \ - \ -void \ -nm_keyfile_plugin_kf_set_##stype##_list (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - set_ctype list[], \ - gsize length) \ -{ \ - const char *alias; \ - \ - alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ - g_key_file_set_##stype##_list (kf, alias ? alias : group, key, list, length); \ -} - -DEFINE_KF_LIST_WRAPPER(integer, gint*, gint); -DEFINE_KF_LIST_WRAPPER(string, gchar **, const gchar* const); - -/* Single value helpers */ -#define DEFINE_KF_WRAPPER(stype, get_ctype, set_ctype) \ -get_ctype \ -nm_keyfile_plugin_kf_get_##stype (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - GError **error) \ -{ \ - get_ctype val; \ - const char *alias; \ - GError *local = NULL; \ - \ - val = g_key_file_get_##stype (kf, group, key, &local); \ - if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { \ - alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ - if (alias) { \ - g_clear_error (&local); \ - val = g_key_file_get_##stype (kf, alias, key, &local); \ - } \ - } \ - if (local) \ - g_propagate_error (error, local); \ - return val; \ -} \ - \ -void \ -nm_keyfile_plugin_kf_set_##stype (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - set_ctype value) \ -{ \ - const char *alias; \ - \ - alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ - g_key_file_set_##stype (kf, alias ? alias : group, key, value); \ -} - -DEFINE_KF_WRAPPER(string, gchar*, const gchar*); -DEFINE_KF_WRAPPER(integer, gint, gint); -DEFINE_KF_WRAPPER(uint64, guint64, guint64); -DEFINE_KF_WRAPPER(boolean, gboolean, gboolean); -DEFINE_KF_WRAPPER(value, gchar*, const gchar*); - - -gchar ** -nm_keyfile_plugin_kf_get_keys (GKeyFile *kf, - const char *group, - gsize *out_length, - GError **error) -{ - gchar **keys; - const char *alias; - GError *local = NULL; - - keys = g_key_file_get_keys (kf, group, out_length, &local); - if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { - alias = nm_keyfile_plugin_get_alias_for_setting_name (group); - if (alias) { - g_clear_error (&local); - keys = g_key_file_get_keys (kf, alias, out_length, &local); - } - } - if (local) - g_propagate_error (error, local); - return keys; -} - -gboolean -nm_keyfile_plugin_kf_has_key (GKeyFile *kf, - const char *group, - const char *key, - GError **error) -{ - gboolean has; - const char *alias; - GError *local = NULL; - - has = g_key_file_has_key (kf, group, key, &local); - if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { - alias = nm_keyfile_plugin_get_alias_for_setting_name (group); - if (alias) { - g_clear_error (&local); - has = g_key_file_has_key (kf, alias, key, &local); - } - } - if (local) - g_propagate_error (error, local); - return has; -} - - diff --git a/src/settings/plugins/keyfile/utils.h b/src/settings/plugins/keyfile/utils.h index 456cd1a88f..d0862284cd 100644 --- a/src/settings/plugins/keyfile/utils.h +++ b/src/settings/plugins/keyfile/utils.h @@ -22,7 +22,6 @@ #define _UTILS_H_ #include <glib.h> -#include "common.h" #include "NetworkManagerUtils.h" #define NM_KEYFILE_CONNECTION_LOG_PATH(path) str_if_set (path,"in-memory") @@ -35,55 +34,5 @@ gboolean nm_keyfile_plugin_utils_should_ignore_file (const char *filename); char *nm_keyfile_plugin_utils_escape_filename (const char *filename); -const char *nm_keyfile_plugin_get_alias_for_setting_name (const char *setting_name); - -const char *nm_keyfile_plugin_get_setting_name_for_alias (const char *alias); - -/*********************************************************/ - -/* List helpers */ -#define DEFINE_KF_LIST_WRAPPER_PROTO(stype, get_ctype, set_ctype) \ -get_ctype nm_keyfile_plugin_kf_get_##stype##_list (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - gsize *out_length, \ - GError **error); \ -\ -void nm_keyfile_plugin_kf_set_##stype##_list (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - set_ctype list[], \ - gsize length); -DEFINE_KF_LIST_WRAPPER_PROTO(integer, gint*, gint) -DEFINE_KF_LIST_WRAPPER_PROTO(string, gchar**, const gchar* const) - -/* Single-value helpers */ -#define DEFINE_KF_WRAPPER_PROTO(stype, get_ctype, set_ctype) \ -get_ctype nm_keyfile_plugin_kf_get_##stype (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - GError **error); \ -\ -void nm_keyfile_plugin_kf_set_##stype (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - set_ctype value); -DEFINE_KF_WRAPPER_PROTO(string, gchar*, const gchar*) -DEFINE_KF_WRAPPER_PROTO(integer, gint, gint) -DEFINE_KF_WRAPPER_PROTO(uint64, guint64, guint64) -DEFINE_KF_WRAPPER_PROTO(boolean, gboolean, gboolean) -DEFINE_KF_WRAPPER_PROTO(value, gchar*, const gchar*) - -/* Misc */ -gchar ** nm_keyfile_plugin_kf_get_keys (GKeyFile *kf, - const char *group, - gsize *out_length, - GError **error); - -gboolean nm_keyfile_plugin_kf_has_key (GKeyFile *kf, - const char *group, - const char *key, - GError **error); - #endif /* _UTILS_H_ */ diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c index 314ff11608..9cf119c0c8 100644 --- a/src/settings/plugins/keyfile/writer.c +++ b/src/settings/plugins/keyfile/writer.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2012 Red Hat, Inc. + * Copyright (C) 2008 - 2015 Red Hat, Inc. */ #include "config.h" @@ -24,407 +24,20 @@ #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> -#include <stdio.h> #include <errno.h> - -#include <nm-setting.h> -#include <nm-setting-connection.h> -#include <nm-setting-ip4-config.h> -#include <nm-setting-ip6-config.h> -#include <nm-setting-vpn.h> -#include <nm-setting-wired.h> -#include <nm-setting-wireless.h> -#include <nm-setting-ip4-config.h> -#include <nm-setting-bluetooth.h> -#include <nm-setting-8021x.h> -#include <nm-utils.h> #include <string.h> -#include <arpa/inet.h> -#include "nm-glib-compat.h" #include "nm-logging.h" #include "writer.h" #include "common.h" #include "utils.h" +#include "nm-keyfile-internal.h" -/* Some setting properties also contain setting names, such as - * NMSettingConnection's 'type' property (which specifies the base type of the - * connection, eg ethernet or wifi) or the 802-11-wireless setting's - * 'security' property which specifies whether or not the AP requires - * encrpytion. This function handles translating those properties' values - * from the real setting name to the more-readable alias. - */ -static void -setting_alias_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) -{ - const char *str, *alias; - - str = g_value_get_string (value); - alias = nm_keyfile_plugin_get_alias_for_setting_name (str); - nm_keyfile_plugin_kf_set_string (file, - nm_setting_get_name (setting), - key, - alias ? alias : str); -} - -static gboolean -write_array_of_uint (GKeyFile *file, - NMSetting *setting, - const char *key, - const GValue *value) -{ - GArray *array; - int i; - int *tmp_array; - - array = (GArray *) g_value_get_boxed (value); - if (!array || !array->len) - return TRUE; - - tmp_array = g_new (gint, array->len); - for (i = 0; i < array->len; i++) - tmp_array[i] = g_array_index (array, int, i); - - nm_keyfile_plugin_kf_set_integer_list (file, nm_setting_get_name (setting), key, tmp_array, array->len); - g_free (tmp_array); - return TRUE; -} - -static void -dns_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) -{ - char **list; - - list = g_value_get_boxed (value); - if (list && list[0]) { - nm_keyfile_plugin_kf_set_string_list (file, nm_setting_get_name (setting), key, - (const char **) list, g_strv_length (list)); - } -} - -static void -write_ip_values (GKeyFile *file, - const char *setting_name, - GPtrArray *array, - const char *gateway, - gboolean is_route) -{ - GString *output; - int family, i; - const char *addr, *gw; - guint32 plen, metric; - char key_name[30], *key_name_idx; - - if (!array->len) - return; - - family = !strcmp (setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME) ? AF_INET : AF_INET6; - - strcpy (key_name, is_route ? "route" : "address"); - key_name_idx = key_name + strlen (key_name); - - output = g_string_sized_new (2*INET_ADDRSTRLEN + 10); - for (i = 0; i < array->len; i++) { - if (is_route) { - NMIPRoute *route = array->pdata[i]; - - addr = nm_ip_route_get_dest (route); - plen = nm_ip_route_get_prefix (route); - gw = nm_ip_route_get_next_hop (route); - metric = MAX (0, nm_ip_route_get_metric (route)); - } else { - NMIPAddress *address = array->pdata[i]; - - addr = nm_ip_address_get_address (address); - plen = nm_ip_address_get_prefix (address); - gw = i == 0 ? gateway : NULL; - metric = 0; - } - - g_string_set_size (output, 0); - g_string_append_printf (output, "%s/%u", addr, plen); - if (metric || gw) { - /* Older versions of the plugin do not support the form - * "a.b.c.d/plen,,metric", so, we always have to write the - * gateway, even if there isn't one. - * The current version supports reading of the above form. - */ - if (!gw) { - if (family == AF_INET) - gw = "0.0.0.0"; - else - gw = "::"; - } - - g_string_append_printf (output, ",%s", gw); - if (metric) - g_string_append_printf (output, ",%lu", (unsigned long) metric); - } - - sprintf (key_name_idx, "%d", i + 1); - nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, output->str); - } - g_string_free (output, TRUE); -} - -static void -addr_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) -{ - GPtrArray *array; - const char *setting_name = nm_setting_get_name (setting); - const char *gateway = nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (setting)); - - array = (GPtrArray *) g_value_get_boxed (value); - if (array && array->len) - write_ip_values (file, setting_name, array, gateway, FALSE); -} - -static void -ip4_addr_label_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) -{ - /* skip */ -} - -static void -gateway_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) -{ - /* skip */ -} - -static void -route_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) -{ - GPtrArray *array; - const char *setting_name = nm_setting_get_name (setting); - - array = (GPtrArray *) g_value_get_boxed (value); - if (array && array->len) - write_ip_values (file, setting_name, array, NULL, TRUE); -} - -static void -write_hash_of_string (GKeyFile *file, - NMSetting *setting, - const char *key, - const GValue *value) -{ - GHashTableIter iter; - const char *property = NULL, *data = NULL; - const char *group_name = nm_setting_get_name (setting); - gboolean vpn_secrets = FALSE; - - /* Write VPN secrets out to a different group to keep them separate */ - if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) { - group_name = VPN_SECRETS_GROUP; - vpn_secrets = TRUE; - } - - g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); - while (g_hash_table_iter_next (&iter, (gpointer *) &property, (gpointer *) &data)) { - gboolean write_item = TRUE; - - /* Handle VPN secrets specially; they are nested in the property's hash; - * we don't want to write them if the secret is not saved, not required, - * or owned by a user's secret agent. - */ - if (vpn_secrets) { - NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; - - nm_setting_get_secret_flags (setting, property, &secret_flags, NULL); - if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) - write_item = FALSE; - } - - if (write_item) - nm_keyfile_plugin_kf_set_string (file, group_name, property, data); - } -} - -static void -ssid_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) -{ - GBytes *bytes; - const guint8 *ssid_data; - gsize ssid_len; - const char *setting_name = nm_setting_get_name (setting); - gboolean new_format = TRUE; - unsigned int semicolons = 0; - int i, *tmp_array; - char *ssid; - - g_return_if_fail (G_VALUE_HOLDS (value, G_TYPE_BYTES)); - - bytes = g_value_get_boxed (value); - if (!bytes) - return; - ssid_data = g_bytes_get_data (bytes, &ssid_len); - if (ssid_len == 0) - return; - - /* Check whether each byte is printable. If not, we have to use an - * integer list, otherwise we can just use a string. - */ - for (i = 0; i < ssid_len; i++) { - char c = ssid_data[i] & 0xFF; - if (!g_ascii_isprint (c)) { - new_format = FALSE; - break; - } - if (c == ';') - semicolons++; - } - if (new_format) { - ssid = g_malloc0 (ssid_len + semicolons + 1); - if (semicolons == 0) - memcpy (ssid, ssid_data, ssid_len); - else { - /* Escape semicolons with backslashes to make strings - * containing ';', such as '16;17;' unambiguous */ - int j = 0; - for (i = 0; i < ssid_len; i++) { - if (ssid_data[i] == ';') - ssid[j++] = '\\'; - ssid[j++] = ssid_data[i]; - } - } - nm_keyfile_plugin_kf_set_string (file, setting_name, key, ssid); - g_free (ssid); - } else { - tmp_array = g_new (gint, ssid_len); - for (i = 0; i < ssid_len; i++) - tmp_array[i] = (int) ssid_data[i]; - nm_keyfile_plugin_kf_set_integer_list (file, setting_name, key, tmp_array, ssid_len); - g_free (tmp_array); - } -} - -static void -password_raw_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) -{ - const char *setting_name = nm_setting_get_name (setting); - GBytes *array; - int *tmp_array; - gsize i, len; - const char *data; - - g_return_if_fail (G_VALUE_HOLDS (value, G_TYPE_BYTES)); - - array = (GBytes *) g_value_get_boxed (value); - if (!array) - return; - data = g_bytes_get_data (array, &len); - if (!data || !len) - return; - - tmp_array = g_new (gint, len); - for (i = 0; i < len; i++) - tmp_array[i] = (int) data[i]; - nm_keyfile_plugin_kf_set_integer_list (file, setting_name, key, tmp_array, len); - g_free (tmp_array); -} +typedef struct { + const char *keyfile_dir; +} WriteInfo; -typedef struct ObjectType { - const char *key; - const char *suffix; - const char *privkey_pw_prop; - NMSetting8021xCKScheme (*scheme_func) (NMSetting8021x *setting); - NMSetting8021xCKFormat (*format_func) (NMSetting8021x *setting); - const char * (*path_func) (NMSetting8021x *setting); - GBytes * (*blob_func) (NMSetting8021x *setting); -} ObjectType; - -static const ObjectType objtypes[10] = { - { NM_SETTING_802_1X_CA_CERT, - "ca-cert", - NULL, - nm_setting_802_1x_get_ca_cert_scheme, - NULL, - nm_setting_802_1x_get_ca_cert_path, - nm_setting_802_1x_get_ca_cert_blob }, - - { NM_SETTING_802_1X_PHASE2_CA_CERT, - "inner-ca-cert", - NULL, - nm_setting_802_1x_get_phase2_ca_cert_scheme, - NULL, - nm_setting_802_1x_get_phase2_ca_cert_path, - nm_setting_802_1x_get_phase2_ca_cert_blob }, - - { NM_SETTING_802_1X_CLIENT_CERT, - "client-cert", - NULL, - nm_setting_802_1x_get_client_cert_scheme, - NULL, - nm_setting_802_1x_get_client_cert_path, - nm_setting_802_1x_get_client_cert_blob }, - - { NM_SETTING_802_1X_PHASE2_CLIENT_CERT, - "inner-client-cert", - NULL, - nm_setting_802_1x_get_phase2_client_cert_scheme, - NULL, - nm_setting_802_1x_get_phase2_client_cert_path, - nm_setting_802_1x_get_phase2_client_cert_blob }, - - { NM_SETTING_802_1X_PRIVATE_KEY, - "private-key", - NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, - nm_setting_802_1x_get_private_key_scheme, - nm_setting_802_1x_get_private_key_format, - nm_setting_802_1x_get_private_key_path, - nm_setting_802_1x_get_private_key_blob }, - - { NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, - "inner-private-key", - NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, - nm_setting_802_1x_get_phase2_private_key_scheme, - nm_setting_802_1x_get_phase2_private_key_format, - nm_setting_802_1x_get_phase2_private_key_path, - nm_setting_802_1x_get_phase2_private_key_blob }, - - { NULL }, -}; static gboolean write_cert_key_file (const char *path, @@ -490,61 +103,75 @@ out: } static void -cert_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) +cert_writer (NMConnection *connection, + GKeyFile *file, + NMKeyfileWriteTypeDataCert *cert_data, + WriteInfo *info, + GError **error) { - const char *setting_name = nm_setting_get_name (setting); + const char *setting_name = nm_setting_get_name (NM_SETTING (cert_data->setting)); NMSetting8021xCKScheme scheme; NMSetting8021xCKFormat format; const char *path = NULL, *ext = "pem"; - const ObjectType *objtype = NULL; - int i; - for (i = 0; i < G_N_ELEMENTS (objtypes) && objtypes[i].key; i++) { - if (g_strcmp0 (objtypes[i].key, key) == 0) { - objtype = &objtypes[i]; - break; - } - } - if (!objtype) { - g_return_if_fail (objtype); - return; - } - - scheme = objtype->scheme_func (NM_SETTING_802_1X (setting)); + scheme = cert_data->scheme_func (cert_data->setting); if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { - path = objtype->path_func (NM_SETTING_802_1X (setting)); + char *tmp = NULL; + const char *accepted_path = NULL; + + path = cert_data->path_func (cert_data->setting); g_assert (path); - /* If the path is rooted in the keyfile directory, just use a - * relative path instead of an absolute one. - */ - if (g_str_has_prefix (path, keyfile_dir)) { - path += strlen (keyfile_dir); - while (*path == '/') - path++; + if (g_str_has_prefix (path, info->keyfile_dir)) { + const char *p = path + strlen (info->keyfile_dir); + + /* If the path is rooted in the keyfile directory, just use a + * relative path instead of an absolute one. + */ + if (*p == '/') { + while (*p == '/') + p++; + if (p[0]) { + /* If @p looks like an integer list, the following detection will fail too and + * we will file:// qualify the path below. We thus avoid writing a path string + * that would be interpreted as legacy binary format by reader. */ + tmp = nm_keyfile_detect_unqualified_path_scheme (info->keyfile_dir, p, -1, FALSE, NULL); + if (tmp) { + g_clear_pointer (&tmp, g_free); + accepted_path = p; + } + } + } + } + if (!accepted_path) { + /* What we are about to write, must also be understood by the reader. + * Otherwise, add a file:// prefix */ + tmp = nm_keyfile_detect_unqualified_path_scheme (info->keyfile_dir, path, -1, FALSE, NULL); + if (tmp) { + g_clear_pointer (&tmp, g_free); + accepted_path = path; + } } - nm_keyfile_plugin_kf_set_string (file, setting_name, key, path); + if (!accepted_path) + accepted_path = tmp = g_strconcat (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, path, NULL); + nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->property_name, accepted_path); + g_free (tmp); } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { GBytes *blob; const guint8 *blob_data; gsize blob_len; gboolean success; - GError *error = NULL; + GError *local = NULL; char *new_path; - blob = objtype->blob_func (NM_SETTING_802_1X (setting)); + blob = cert_data->blob_func (cert_data->setting); g_assert (blob); blob_data = g_bytes_get_data (blob, &blob_len); - if (objtype->format_func) { + if (cert_data->format_func) { /* Get the extension for a private key */ - format = objtype->format_func (NM_SETTING_802_1X (setting)); + format = cert_data->format_func (cert_data->setting); if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) ext = "p12"; } else { @@ -556,226 +183,46 @@ cert_writer (GKeyFile *file, /* Write the raw data out to the standard file so that we can use paths * from now on instead of pushing around the certificate data. */ - new_path = g_strdup_printf ("%s/%s-%s.%s", keyfile_dir, uuid, objtype->suffix, ext); - g_assert (new_path); + new_path = g_strdup_printf ("%s/%s-%s.%s", info->keyfile_dir, nm_connection_get_uuid (connection), + cert_data->suffix, ext); - success = write_cert_key_file (new_path, blob_data, blob_len, &error); + success = write_cert_key_file (new_path, blob_data, blob_len, &local); if (success) { - /* Write the path value to the keyfile */ - nm_keyfile_plugin_kf_set_string (file, setting_name, key, new_path); + /* Write the path value to the keyfile. + * We know, that basename(new_path) starts with a UUID, hence no conflict with "data:;base64," */ + nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->property_name, strrchr (new_path, '/') + 1); } else { - nm_log_warn (LOGD_SETTINGS, "Failed to write certificate/key %s: %s", - new_path, error->message); - g_error_free (error); + nm_log_warn (LOGD_SETTINGS, "keyfile: %s.%s: failed to write certificate to file %s: %s", + setting_name, cert_data->property_name, new_path, local->message); + g_error_free (local); } g_free (new_path); - } else - g_assert_not_reached (); + } else { + /* scheme_func() returns UNKNOWN in all other cases. The only valid case + * where a scheme is allowed to be UNKNOWN, is unsetting the value. In this + * case, we don't expect the writer to be called, because the default value + * will not be serialized. + * The only other reason for the scheme to be UNKNOWN is an invalid cert. + * But our connection verifies, so that cannot happen either. */ + g_return_if_reached (); + } } -typedef struct { - const char *setting_name; - const char *key; - void (*writer) (GKeyFile *keyfile, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value); -} KeyWriter; - -/* A table of keys that require further parsing/conversion because they are - * stored in a format that can't be automatically read using the key's type. - * i.e. IPv4 addresses, which are stored in NetworkManager as guint32, but are - * stored in keyfiles as strings, eg "10.1.1.2" or IPv6 addresses stored - * in struct in6_addr internally, but as string in keyfiles. - */ -static KeyWriter key_writers[] = { - { NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_TYPE, - setting_alias_writer }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_ADDRESSES, - addr_writer }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, - "address-labels", - ip4_addr_label_writer }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_ADDRESSES, - addr_writer }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_GATEWAY, - gateway_writer }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_GATEWAY, - gateway_writer }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_ROUTES, - route_writer }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_ROUTES, - route_writer }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_DNS, - dns_writer }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP_CONFIG_DNS, - dns_writer }, - { NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_SSID, - ssid_writer }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_PASSWORD_RAW, - password_raw_writer }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_CA_CERT, - cert_writer }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_CLIENT_CERT, - cert_writer }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_PRIVATE_KEY, - cert_writer }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_PHASE2_CA_CERT, - cert_writer }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_PHASE2_CLIENT_CERT, - cert_writer }, - { NM_SETTING_802_1X_SETTING_NAME, - NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, - cert_writer }, - { NULL, NULL, NULL } -}; - -typedef struct { - GKeyFile *keyfile; - const char *keyfile_dir; - const char *uuid; -} WriteInfo; - -static void -write_setting_value (NMSetting *setting, - const char *key, - const GValue *value, - GParamFlags flag, - gpointer user_data) +static gboolean +_handler_write (NMConnection *connection, + GKeyFile *keyfile, + NMKeyfileWriteType type, + void *type_data, + void *user_data, + GError **error) { - WriteInfo *info = user_data; - const char *setting_name; - GType type = G_VALUE_TYPE (value); - KeyWriter *writer = &key_writers[0]; - GParamSpec *pspec; - - /* Setting name gets picked up from the keyfile's section name instead */ - if (!strcmp (key, NM_SETTING_NAME)) - return; - - /* Don't write the NMSettingConnection object's 'read-only' property */ - if ( NM_IS_SETTING_CONNECTION (setting) - && !strcmp (key, NM_SETTING_CONNECTION_READ_ONLY)) - return; - - setting_name = nm_setting_get_name (setting); - - /* If the value is the default value, remove the item from the keyfile */ - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), key); - if (pspec) { - if (g_param_value_defaults (pspec, (GValue *) value)) { - g_key_file_remove_key (info->keyfile, setting_name, key, NULL); - return; - } - } - - /* Don't write secrets that are owned by user secret agents or aren't - * supposed to be saved. VPN secrets are handled specially though since - * the secret flags there are in a third-level hash in the 'secrets' - * property. - */ - if (pspec && (pspec->flags & NM_SETTING_PARAM_SECRET) && !NM_IS_SETTING_VPN (setting)) { - NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; - - if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) - g_assert_not_reached (); - if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) - return; - } - - /* Look through the list of handlers for non-standard format key values */ - while (writer->setting_name) { - if (!strcmp (writer->setting_name, setting_name) && !strcmp (writer->key, key)) { - (*writer->writer) (info->keyfile, info->keyfile_dir, info->uuid, setting, key, value); - return; - } - writer++; - } - - if (type == G_TYPE_STRING) { - const char *str; - - str = g_value_get_string (value); - if (str) - nm_keyfile_plugin_kf_set_string (info->keyfile, setting_name, key, str); - } else if (type == G_TYPE_UINT) - nm_keyfile_plugin_kf_set_integer (info->keyfile, setting_name, key, (int) g_value_get_uint (value)); - else if (type == G_TYPE_INT) - nm_keyfile_plugin_kf_set_integer (info->keyfile, setting_name, key, g_value_get_int (value)); - else if (type == G_TYPE_UINT64) { - char *numstr; - - numstr = g_strdup_printf ("%" G_GUINT64_FORMAT, g_value_get_uint64 (value)); - nm_keyfile_plugin_kf_set_value (info->keyfile, setting_name, key, numstr); - g_free (numstr); - } else if (type == G_TYPE_INT64) { - char *numstr; - - numstr = g_strdup_printf ("%" G_GINT64_FORMAT, g_value_get_int64 (value)); - nm_keyfile_plugin_kf_set_value (info->keyfile, setting_name, key, numstr); - g_free (numstr); - } else if (type == G_TYPE_BOOLEAN) { - nm_keyfile_plugin_kf_set_boolean (info->keyfile, setting_name, key, g_value_get_boolean (value)); - } else if (type == G_TYPE_CHAR) { - nm_keyfile_plugin_kf_set_integer (info->keyfile, setting_name, key, (int) g_value_get_schar (value)); - } else if (type == G_TYPE_BYTES) { - GBytes *bytes; - const guint8 *data; - gsize len = 0; - - bytes = g_value_get_boxed (value); - data = bytes ? g_bytes_get_data (bytes, &len) : NULL; - - if (data != NULL && len > 0) { - int *tmp_array; - int i; - - tmp_array = g_new (gint, len); - for (i = 0; i < len; i++) - tmp_array[i] = (int) data[i]; - - nm_keyfile_plugin_kf_set_integer_list (info->keyfile, setting_name, key, tmp_array, len); - g_free (tmp_array); - } - } else if (type == G_TYPE_STRV) { - char **array; - - array = (char **) g_value_get_boxed (value); - nm_keyfile_plugin_kf_set_string_list (info->keyfile, setting_name, key, (const gchar **const) array, g_strv_length (array)); - } else if (type == G_TYPE_HASH_TABLE) { - write_hash_of_string (info->keyfile, setting, key, value); - } else if (type == G_TYPE_ARRAY) { - if (!write_array_of_uint (info->keyfile, setting, key, value)) { - nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (write) '%s/%s' : '%s'", - setting_name, key, g_type_name (type)); - } - } else if (G_VALUE_HOLDS_FLAGS (value)) { - /* Flags are guint but GKeyFile has no uint reader, just uint64 */ - nm_keyfile_plugin_kf_set_uint64 (info->keyfile, setting_name, key, (guint64) g_value_get_flags (value)); - } else if (G_VALUE_HOLDS_ENUM (value)) - nm_keyfile_plugin_kf_set_integer (info->keyfile, setting_name, key, (gint) g_value_get_enum (value)); - else { - nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (write) '%s/%s' : '%s'", - setting_name, key, g_type_name (type)); + if (type == NM_KEYFILE_WRITE_TYPE_CERT) { + cert_writer (connection, keyfile, + (NMKeyfileWriteTypeDataCert *) type_data, + (WriteInfo *) user_data, error); + return TRUE; } + return FALSE; } static gboolean @@ -793,10 +240,11 @@ _internal_write_connection (NMConnection *connection, gboolean success = FALSE; char *path; const char *id; - WriteInfo info; + WriteInfo info = { 0 }; GError *local_err = NULL; g_return_val_if_fail (!out_path || !*out_path, FALSE); + g_return_val_if_fail (keyfile_dir && keyfile_dir[0] == '/', FALSE); if (!nm_connection_verify (connection, error)) g_return_val_if_reached (FALSE); @@ -804,14 +252,15 @@ _internal_write_connection (NMConnection *connection, id = nm_connection_get_id (connection); g_assert (id && *id); - info.keyfile = key_file = g_key_file_new (); info.keyfile_dir = keyfile_dir; - info.uuid = nm_connection_get_uuid (connection); - g_assert (info.uuid); - nm_connection_for_each_setting_value (connection, write_setting_value, &info); + + key_file = nm_keyfile_write (connection, _handler_write, &info, error); + if (!key_file) + return FALSE; data = g_key_file_to_data (key_file, &len, error); + g_key_file_unref (key_file); if (!data) - goto out; + return FALSE; /* If we have existing file path, use it. Else generate one from * connection's ID. @@ -910,7 +359,6 @@ _internal_write_connection (NMConnection *connection, out: g_free (data); - g_key_file_free (key_file); return success; } diff --git a/src/settings/plugins/keyfile/writer.h b/src/settings/plugins/keyfile/writer.h index a602f2f4a3..8b08812d86 100644 --- a/src/settings/plugins/keyfile/writer.h +++ b/src/settings/plugins/keyfile/writer.h @@ -22,7 +22,6 @@ #ifndef _KEYFILE_PLUGIN_WRITER_H #define _KEYFILE_PLUGIN_WRITER_H -#include <sys/types.h> #include <glib.h> #include <nm-connection.h> diff --git a/src/tests/test-general.c b/src/tests/test-general.c index 21533cc743..dae872c86d 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -30,135 +30,6 @@ #include "nm-test-utils.h" -static void -test_nm_utils_ascii_str_to_int64_check (const char *str, guint base, gint64 min, - gint64 max, gint64 fallback, int exp_errno, - gint64 exp_val) -{ - gint64 v; - - errno = 1; - v = nm_utils_ascii_str_to_int64 (str, base, min, max, fallback); - g_assert_cmpint (errno, ==, exp_errno); - g_assert_cmpint (v, ==, exp_val); -} - -static void -test_nm_utils_ascii_str_to_int64_do (const char *str, guint base, gint64 min, - gint64 max, gint64 fallback, int exp_errno, - gint64 exp_val) -{ - const char *sign = ""; - const char *val; - static const char *whitespaces[] = { - "", - " ", - "\r\n\t", - " \r\n\t ", - " \r\n\t \t\r\n\t", - NULL, - }; - static const char *nulls[] = { - "", - "0", - "00", - "0000", - "0000000000000000", - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - NULL, - }; - const char **ws_pre, **ws_post, **null; - guint i; - - if (str == NULL || exp_errno != 0) { - test_nm_utils_ascii_str_to_int64_check (str, base, min, max, fallback, exp_errno, exp_val); - return; - } - - if (strncmp (str, "-", 1) == 0) - sign = "-"; - - val = str + strlen (sign); - - for (ws_pre = whitespaces; *ws_pre; ws_pre++) { - for (ws_post = whitespaces; *ws_post; ws_post++) { - for (null = nulls; *null; null++) { - for (i = 0; ; i++) { - char *s; - const char *str_base = ""; - - if (base == 16) { - if (i == 1) - str_base = "0x"; - else if (i > 1) - break; - } else if (base == 8) { - if (i == 1) - str_base = "0"; - else if (i > 1) - break; - } else if (base == 0) { - if (i > 0) - break; - /* with base==0, a leading zero would be interpreted as octal. Only test without *null */ - if ((*null)[0]) - break; - } else { - if (i > 0) - break; - } - - s = g_strdup_printf ("%s%s%s%s%s%s", *ws_pre, sign, str_base, *null, val, *ws_post); - - test_nm_utils_ascii_str_to_int64_check (s, base, min, max, fallback, exp_errno, exp_val); - g_free (s); - } - } - } - } -} - -static void -test_nm_utils_ascii_str_to_int64 (void) -{ - test_nm_utils_ascii_str_to_int64_do (NULL, 10, 0, 10000, -1, EINVAL, -1); - test_nm_utils_ascii_str_to_int64_do ("", 10, 0, 10000, -1, EINVAL, -1); - test_nm_utils_ascii_str_to_int64_do ("1x", 10, 0, 10000, -1, EINVAL, -1); - test_nm_utils_ascii_str_to_int64_do ("4711", 10, 0, 10000, -1, 0, 4711); - test_nm_utils_ascii_str_to_int64_do ("10000", 10, 0, 10000, -1, 0, 10000); - test_nm_utils_ascii_str_to_int64_do ("10001", 10, 0, 10000, -1, ERANGE, -1); - test_nm_utils_ascii_str_to_int64_do ("FF", 16, 0, 10000, -1, 0, 255); - test_nm_utils_ascii_str_to_int64_do ("FF", 10, 0, 10000, -2, EINVAL, -2); - test_nm_utils_ascii_str_to_int64_do ("9223372036854775807", 10, 0, G_MAXINT64, -2, 0, G_MAXINT64); - test_nm_utils_ascii_str_to_int64_do ("7FFFFFFFFFFFFFFF", 16, 0, G_MAXINT64, -2, 0, G_MAXINT64); - test_nm_utils_ascii_str_to_int64_do ("9223372036854775808", 10, 0, G_MAXINT64, -2, ERANGE, -2); - test_nm_utils_ascii_str_to_int64_do ("-9223372036854775808", 10, G_MININT64, 0, -2, 0, G_MININT64); - test_nm_utils_ascii_str_to_int64_do ("-9223372036854775808", 10, G_MININT64+1, 0, -2, ERANGE, -2); - test_nm_utils_ascii_str_to_int64_do ("-9223372036854775809", 10, G_MININT64, 0, -2, ERANGE, -2); - test_nm_utils_ascii_str_to_int64_do ("1.0", 10, 1, 1, -1, EINVAL, -1); - test_nm_utils_ascii_str_to_int64_do ("1x0", 16, -10, 10, -100, EINVAL, -100); - test_nm_utils_ascii_str_to_int64_do ("0", 16, -10, 10, -100, 0, 0); - test_nm_utils_ascii_str_to_int64_do ("10001111", 2, -1000, 1000, -100000, 0, 0x8F); - test_nm_utils_ascii_str_to_int64_do ("-10001111", 2, -1000, 1000, -100000, 0, -0x8F); - test_nm_utils_ascii_str_to_int64_do ("1111111", 2, G_MININT64, G_MAXINT64, -1, 0, 0x7F); - test_nm_utils_ascii_str_to_int64_do ("111111111111111", 2, G_MININT64, G_MAXINT64, -1, 0, 0x7FFF); - test_nm_utils_ascii_str_to_int64_do ("11111111111111111111111111111111111111111111111", 2, G_MININT64, G_MAXINT64, -1, 0, 0x7FFFFFFFFFFF); - test_nm_utils_ascii_str_to_int64_do ("111111111111111111111111111111111111111111111111111111111111111", 2, G_MININT64, G_MAXINT64, -1, 0, 0x7FFFFFFFFFFFFFFF); - test_nm_utils_ascii_str_to_int64_do ("100000000000000000000000000000000000000000000000000000000000000", 2, G_MININT64, G_MAXINT64, -1, 0, 0x4000000000000000); - test_nm_utils_ascii_str_to_int64_do ("1000000000000000000000000000000000000000000000000000000000000000", 2, G_MININT64, G_MAXINT64, -1, ERANGE, -1); - test_nm_utils_ascii_str_to_int64_do ("-100000000000000000000000000000000000000000000000000000000000000", 2, G_MININT64, G_MAXINT64, -1, 0, -0x4000000000000000); - test_nm_utils_ascii_str_to_int64_do ("111111111111111111111111111111111111111111111111111111111111111", 2, G_MININT64, G_MAXINT64, -1, 0, 0x7FFFFFFFFFFFFFFF); - test_nm_utils_ascii_str_to_int64_do ("-100000000000000000000000000000000000000000000000000000000000000", 2, G_MININT64, G_MAXINT64, -1, 0, -0x4000000000000000); - test_nm_utils_ascii_str_to_int64_do ("0x70", 10, G_MININT64, G_MAXINT64, -1, EINVAL, -1); - test_nm_utils_ascii_str_to_int64_do ("4711", 0, G_MININT64, G_MAXINT64, -1, 0, 4711); - test_nm_utils_ascii_str_to_int64_do ("04711", 0, G_MININT64, G_MAXINT64, -1, 0, 04711); - test_nm_utils_ascii_str_to_int64_do ("0x4711", 0, G_MININT64, G_MAXINT64, -1, 0, 0x4711); - test_nm_utils_ascii_str_to_int64_do ("080", 0, G_MININT64, G_MAXINT64, -1, EINVAL, -1); - test_nm_utils_ascii_str_to_int64_do ("070", 0, G_MININT64, G_MAXINT64, -1, 0, 7*8); - test_nm_utils_ascii_str_to_int64_do ("0x70", 0, G_MININT64, G_MAXINT64, -1, 0, 0x70); -} - /* Reference implementation for nm_utils_ip6_address_clear_host_address. * Taken originally from set_address_masked(), src/rdisc/nm-lndp-rdisc.c **/ @@ -727,53 +598,6 @@ test_connection_sort_autoconnect_priority (void) /*******************************************/ -static void -__test_uuid (const char *expected_uuid, const char *str, gssize slen, char *uuid_test) -{ - g_assert (uuid_test); - g_assert (nm_utils_is_uuid (uuid_test)); - - if (strcmp (uuid_test, expected_uuid)) { - g_error ("UUID test failed (1): text=%s, len=%lld, expected=%s, uuid_test=%s", - str, (long long) slen, expected_uuid, uuid_test); - } - g_free (uuid_test); - - uuid_test = nm_utils_uuid_generate_from_string (str, slen, NM_UTILS_UUID_TYPE_VARIANT3, NM_UTILS_UUID_NS); - - g_assert (uuid_test); - g_assert (nm_utils_is_uuid (uuid_test)); - - if (strcmp (uuid_test, expected_uuid)) { - g_error ("UUID test failed (2): text=%s; len=%lld, expected=%s, uuid2=%s", - str, (long long) slen, expected_uuid, uuid_test); - } - g_free (uuid_test); -} - -#define _test_uuid(expected_uuid, str, strlen, ...) __test_uuid (expected_uuid, str, strlen, nm_utils_uuid_generate_from_strings(__VA_ARGS__, NULL)) - -static void -test_nm_utils_uuid_generate_from_strings (void) -{ - _test_uuid ("b07c334a-399b-32de-8d50-58e4e08f98e3", "", 0, NULL); - _test_uuid ("b8a426cb-bcb5-30a3-bd8f-6786fea72df9", "\0", 1, ""); - _test_uuid ("12a4a982-7aae-39e1-951e-41aeb1250959", "a\0", 2, "a"); - _test_uuid ("69e22c7e-f89f-3a43-b239-1cb52ed8db69", "aa\0", 3, "aa"); - _test_uuid ("59829fd3-5ad5-3d90-a7b0-4911747e4088", "\0\0", 2, "", ""); - _test_uuid ("01ad0e06-6c50-3384-8d86-ddab81421425", "a\0\0", 3, "a", ""); - _test_uuid ("e1ed8647-9ed3-3ec8-8c6d-e8204524d71d", "aa\0\0", 4, "aa", ""); - _test_uuid ("fb1c7cd6-275c-3489-9382-83b900da8af0", "\0a\0", 3, "", "a"); - _test_uuid ("5d79494e-c4ba-31a6-80a2-d6016ccd7e17", "a\0a\0", 4, "a", "a"); - _test_uuid ("fd698d86-1b60-3ebe-855f-7aada9950a8d", "aa\0a\0", 5, "aa", "a"); - _test_uuid ("8c573b48-0f01-30ba-bb94-c5f59f4fe517", "\0aa\0", 4, "", "aa"); - _test_uuid ("2bdd3d46-eb83-3c53-a41b-a724d04b5544", "a\0aa\0", 5, "a", "aa"); - _test_uuid ("13d4b780-07c1-3ba7-b449-81c4844ef039", "aa\0aa\0", 6, "aa", "aa"); - _test_uuid ("dd265bf7-c05a-3037-9939-b9629858a477", "a\0b\0", 4, "a", "b"); -} - -/*******************************************/ - static const char *_test_match_spec_all[] = { "e", "em", @@ -893,7 +717,6 @@ main (int argc, char **argv) { nmtst_init_with_logging (&argc, &argv, NULL, "ALL"); - g_test_add_func ("/general/nm_utils_ascii_str_to_int64", test_nm_utils_ascii_str_to_int64); g_test_add_func ("/general/nm_utils_ip6_address_clear_host_address", test_nm_utils_ip6_address_clear_host_address); g_test_add_func ("/general/nm_utils_log_connection_diff", test_nm_utils_log_connection_diff); @@ -908,7 +731,6 @@ main (int argc, char **argv) g_test_add_func ("/general/connection-sort/autoconnect-priority", test_connection_sort_autoconnect_priority); - g_test_add_func ("/general/nm_utils_uuid_generate_from_strings", test_nm_utils_uuid_generate_from_strings); g_test_add_func ("/general/nm_match_spec_interface_name", test_nm_match_spec_interface_name); return g_test_run (); |