From 9959fdb2e8ddd06f2161798ca0a39c77d67c652d Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Wed, 4 May 2022 15:35:24 +0200 Subject: New upstream version 1.37.92 --- src/libnm-client-impl/libnm.ver | 8 +- src/libnm-client-impl/meson.build | 8 ++ src/libnm-client-impl/nm-client.c | 47 ++++++++- src/libnm-client-impl/nm-libnm-utils.c | 57 ++++++++++ .../nm-property-infos-ifcfg-rh.xml | 2 +- src/libnm-client-impl/nm-property-infos-nmcli.xml | 10 +- src/libnm-client-impl/nm-settings-docs-gir.xml | 6 +- src/libnm-client-impl/nm-vpn-service-plugin.c | 88 +++++----------- src/libnm-client-impl/tests/test-libnm.c | 117 +++++++++++++++++++-- 9 files changed, 259 insertions(+), 84 deletions(-) (limited to 'src/libnm-client-impl') diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver index bb691ac2..b6d566fc 100644 --- a/src/libnm-client-impl/libnm.ver +++ b/src/libnm-client-impl/libnm.ver @@ -1820,4 +1820,10 @@ global: libnm_1_36_0 { global: nm_setting_ovs_dpdk_get_n_rxq; -} libnm_1_34_0; \ No newline at end of file +} libnm_1_34_0; + +libnm_1_38_0 { +global: + nm_client_get_radio_flags; + nm_radio_flags_get_type; +} libnm_1_36_0; \ No newline at end of file diff --git a/src/libnm-client-impl/meson.build b/src/libnm-client-impl/meson.build index 21a01e0b..2026f98d 100644 --- a/src/libnm-client-impl/meson.build +++ b/src/libnm-client-impl/meson.build @@ -140,6 +140,14 @@ if enable_introspection src_inc, top_inc, ], + dependencies: [ + declare_dependency( + compile_args: [ + '-UGLIB_VERSION_MIN_REQUIRED', + '-UGLIB_VERSION_MAX_ALLOWED', + ], + ), + ], nsversion: nm_gir_version, namespace: 'NM', identifier_prefix: nm_id_prefix, diff --git a/src/libnm-client-impl/nm-client.c b/src/libnm-client-impl/nm-client.c index cd2aa730..b18f47be 100644 --- a/src/libnm-client-impl/nm-client.c +++ b/src/libnm-client-impl/nm-client.c @@ -198,6 +198,7 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMClient, PROP_WWAN_HARDWARE_ENABLED, PROP_WIMAX_ENABLED, PROP_WIMAX_HARDWARE_ENABLED, + PROP_RADIO_FLAGS, PROP_ACTIVE_CONNECTIONS, PROP_CONNECTIVITY, PROP_CONNECTIVITY_CHECK_URI, @@ -307,6 +308,7 @@ typedef struct { guint32 connectivity; guint32 state; guint32 metered; + guint32 radio_flags; bool connectivity_check_available; bool connectivity_check_enabled; bool networking_enabled; @@ -4235,6 +4237,24 @@ nm_client_wireless_hardware_get_enabled(NMClient *client) return NM_CLIENT_GET_PRIVATE(client)->nm.wireless_hardware_enabled; } +/** + * nm_client_get_radio_flags: + * @client: a #NMClient + * + * Get radio flags. + * + * Returns: the #NMRadioFlags. + * + * Since: 1.38 + **/ +NMRadioFlags +nm_client_get_radio_flags(NMClient *client) +{ + g_return_val_if_fail(NM_IS_CLIENT(client), NM_RADIO_FLAG_NONE); + + return NM_CLIENT_GET_PRIVATE(client)->nm.radio_flags; +} + /** * nm_client_wwan_get_enabled: * @client: a #NMClient @@ -7349,7 +7369,10 @@ _init_start_with_bus(NMClient *self) NULL); if (id == 0) { priv->init_data->cancel_on_idle_source = - nm_g_idle_source_new(G_PRIORITY_DEFAULT, _init_start_cancel_on_idle_cb, self, NULL); + nm_g_idle_source_new(G_PRIORITY_DEFAULT_IDLE, + _init_start_cancel_on_idle_cb, + self, + NULL); g_source_attach(priv->init_data->cancel_on_idle_source, priv->main_context); return; } @@ -7451,6 +7474,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) case PROP_WIRELESS_HARDWARE_ENABLED: g_value_set_boolean(value, nm_client_wireless_hardware_get_enabled(self)); break; + case PROP_RADIO_FLAGS: + g_value_set_uint(value, priv->nm.radio_flags); + break; case PROP_WWAN_ENABLED: g_value_set_boolean(value, nm_client_wwan_get_enabled(self)); break; @@ -8043,6 +8069,10 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm = NML_DBUS_META_IFACE_INIT_PROP( _priv.nm.property_o[PROPERTY_O_IDX_NM_PRIMAY_CONNECTION], nm_active_connection_get_type), NML_DBUS_META_PROPERTY_INIT_IGNORE("PrimaryConnectionType", "s"), + NML_DBUS_META_PROPERTY_INIT_U("RadioFlags", + PROP_RADIO_FLAGS, + NMClient, + _priv.nm.radio_flags), NML_DBUS_META_PROPERTY_INIT_B("Startup", PROP_STARTUP, NMClient, _priv.nm.startup), NML_DBUS_META_PROPERTY_INIT_U("State", PROP_STATE, NMClient, _priv.nm.state), NML_DBUS_META_PROPERTY_INIT_S("Version", PROP_VERSION, NMClient, _priv.nm.version), @@ -8310,6 +8340,21 @@ nm_client_class_init(NMClientClass *client_class) FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /** + * NMClient:radio-flags: + * + * Flags for radio interfaces. See #NMRadioFlags. + * + * Since: 1.38 + **/ + obj_properties[PROP_RADIO_FLAGS] = g_param_spec_uint(NM_CLIENT_RADIO_FLAGS, + "", + "", + 0, + G_MAXUINT32, + NM_RADIO_FLAG_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /** * NMClient:active-connections: (type GPtrArray(NMActiveConnection)) * diff --git a/src/libnm-client-impl/nm-libnm-utils.c b/src/libnm-client-impl/nm-libnm-utils.c index d3d429eb..951db1bc 100644 --- a/src/libnm-client-impl/nm-libnm-utils.c +++ b/src/libnm-client-impl/nm-libnm-utils.c @@ -10,7 +10,9 @@ #include "libnm-glib-aux/nm-time-utils.h" #include "libnm-core-aux-intern/nm-common-macros.h" +#include "libnm-crypto/nm-crypto.h" #include "nm-object.h" +#include "nm-utils.h" /*****************************************************************************/ @@ -914,3 +916,58 @@ nm_utils_print(int output_mode, const char *msg) else g_return_if_reached(); } + +/*****************************************************************************/ + +/** + * nm_utils_file_is_certificate: + * @filename: name of the file to test + * + * Tests if @filename has a valid extension for an X.509 certificate file + * (".cer", ".crt", ".der", or ".pem"), and contains a certificate in a format + * recognized by NetworkManager. + * + * Returns: %TRUE if the file is a certificate, %FALSE if it is not + **/ +gboolean +nm_utils_file_is_certificate(const char *filename) +{ + g_return_val_if_fail(filename != NULL, FALSE); + + return nm_crypto_utils_file_is_certificate(filename); +} + +/** + * nm_utils_file_is_private_key: + * @filename: name of the file to test + * @out_encrypted: (out): on return, whether the file is encrypted + * + * Tests if @filename has a valid extension for an X.509 private key file + * (".der", ".key", ".pem", or ".p12"), and contains a private key in a format + * recognized by NetworkManager. + * + * Returns: %TRUE if the file is a private key, %FALSE if it is not + **/ +gboolean +nm_utils_file_is_private_key(const char *filename, gboolean *out_encrypted) +{ + g_return_val_if_fail(filename != NULL, FALSE); + + return nm_crypto_utils_file_is_private_key(filename, out_encrypted); +} + +/** + * nm_utils_file_is_pkcs12: + * @filename: name of the file to test + * + * Tests if @filename is a PKCS#12 file. + * + * Returns: %TRUE if the file is PKCS#12, %FALSE if it is not + **/ +gboolean +nm_utils_file_is_pkcs12(const char *filename) +{ + g_return_val_if_fail(filename != NULL, FALSE); + + return nm_crypto_is_pkcs12_file(filename, NULL); +} diff --git a/src/libnm-client-impl/nm-property-infos-ifcfg-rh.xml b/src/libnm-client-impl/nm-property-infos-ifcfg-rh.xml index 91d04e13..d051725d 100644 --- a/src/libnm-client-impl/nm-property-infos-ifcfg-rh.xml +++ b/src/libnm-client-impl/nm-property-infos-ifcfg-rh.xml @@ -31,7 +31,7 @@ - + diff --git a/src/libnm-client-impl/nm-property-infos-nmcli.xml b/src/libnm-client-impl/nm-property-infos-nmcli.xml index 3d067745..8e39a7a2 100644 --- a/src/libnm-client-impl/nm-property-infos-nmcli.xml +++ b/src/libnm-client-impl/nm-property-infos-nmcli.xml @@ -71,7 +71,8 @@ Various attributes are supported: "type" - one of unicast, local, blackhole, -unavailable, prohibit. The default is unicast. +unavailable, prohibit, throw. +The default is unicast. "window" - an unsigned 32 bit integer. @@ -90,7 +91,7 @@ fixed priority. Example: priority 5 from 192.167.4.0/24 table 45 - + A list of IPv6 destination addresses, prefix length, optional IPv6 next hop addresses, optional route metric, optional attribute. The valid syntax is: @@ -140,7 +141,8 @@ Various attributes are supported: "type" - one of unicast, local, blackhole, -unavailable, prohibit. The default is unicast. +unavailable, prohibit, throw. +The default is unicast. "window" - an unsigned 32 bit integer. @@ -171,7 +173,7 @@ Example: priority 5 from 1:2:3::5/128 table 45 - + diff --git a/src/libnm-client-impl/nm-settings-docs-gir.xml b/src/libnm-client-impl/nm-settings-docs-gir.xml index d8022132..77a95b51 100644 --- a/src/libnm-client-impl/nm-settings-docs-gir.xml +++ b/src/libnm-client-impl/nm-settings-docs-gir.xml @@ -5,7 +5,7 @@ - + @@ -24,7 +24,7 @@ - + @@ -353,7 +353,7 @@ - + diff --git a/src/libnm-client-impl/nm-vpn-service-plugin.c b/src/libnm-client-impl/nm-vpn-service-plugin.c index 2a217502..3493d1db 100644 --- a/src/libnm-client-impl/nm-vpn-service-plugin.c +++ b/src/libnm-client-impl/nm-vpn-service-plugin.c @@ -729,54 +729,6 @@ nm_vpn_service_plugin_secrets_required(NMVpnServicePlugin *plugin, /*****************************************************************************/ -typedef struct { - char *buf; - gsize n_buf; - int fd; - bool eof : 1; - char buf_full[1024]; -} ReadFdBuf; - -static inline gboolean -_read_fd_buf_c(ReadFdBuf *read_buf, char *ch) -{ - gssize n_read; - - if (read_buf->n_buf > 0) - goto out_data; - if (read_buf->eof) - return FALSE; - -again: - n_read = read(read_buf->fd, read_buf->buf_full, sizeof(read_buf->buf_full)); - if (n_read <= 0) { - if (n_read < 0 && errno == EAGAIN) { - struct pollfd pfd; - int r; - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = read_buf->fd; - pfd.events = POLLIN; - - r = poll(&pfd, 1, -1); - if (r > 0) - goto again; - /* error or timeout. Fall through and set EOF. */ - } - read_buf->eof = TRUE; - return FALSE; - } - - read_buf->buf = read_buf->buf_full; - read_buf->n_buf = n_read; - -out_data: - read_buf->n_buf--; - *ch = read_buf->buf[0]; - read_buf->buf++; - return TRUE; -} - #define DATA_KEY_TAG "DATA_KEY=" #define DATA_VAL_TAG "DATA_VAL=" #define SECRET_KEY_TAG "SECRET_KEY=" @@ -808,7 +760,7 @@ nm_vpn_service_plugin_read_vpn_details(int fd, GHashTable **out_data, GHashTable nm_auto_free_gstring GString *val = NULL; nm_auto_free_gstring GString *line = NULL; GString *str = NULL; - ReadFdBuf read_buf; + char c; if (out_data) g_return_val_if_fail(*out_data == NULL, FALSE); @@ -819,27 +771,37 @@ nm_vpn_service_plugin_read_vpn_details(int fd, GHashTable **out_data, GHashTable secrets = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, (GDestroyNotify) nm_free_secret); - read_buf.buf = NULL; - read_buf.n_buf = 0; - read_buf.fd = fd; - read_buf.eof = FALSE; - line = g_string_new(NULL); /* Read stdin for data and secret items until we get a DONE */ while (1) { - gboolean eof; - char c = '\0'; + ssize_t nr; + + nr = read(fd, &c, 1); + if (nr < 0) { + if (errno == EAGAIN) { + struct pollfd pfd; + int r; - eof = !_read_fd_buf_c(&read_buf, &c); + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = fd; + pfd.events = POLLIN; + + r = poll(&pfd, 1, -1); + if (r > 0) + continue; + + /* error or timeout. Fall through and break. */ + } + break; + } - if (!eof && c == '\0') { - /* On the first '\0' char, we also assume the data is finished. Abort. */ - read_buf.eof = TRUE; - eof = TRUE; + if (nr > 0 && c == '\0') { + /* '\0' are not supported. Replace with newline. */ + c = '\n'; } - if (!eof && c != '\n') { + if (nr > 0 && c != '\n') { g_string_append_c(line, c); if (line->len > 512 * 1024) { /* we are about to read a huge line. That is not right, abort. */ @@ -893,7 +855,7 @@ nm_vpn_service_plugin_read_vpn_details(int fd, GHashTable **out_data, GHashTable next: g_string_truncate(line, 0); - if (eof) + if (nr == 0) break; } diff --git a/src/libnm-client-impl/tests/test-libnm.c b/src/libnm-client-impl/tests/test-libnm.c index 0f600a4a..1810e139 100644 --- a/src/libnm-client-impl/tests/test-libnm.c +++ b/src/libnm-client-impl/tests/test-libnm.c @@ -2272,6 +2272,12 @@ _memfd_create(const char *name) return -1; } +typedef enum { + READ_VPN_DETAIL_TYPE_GOOD, + READ_VPN_DETAIL_TYPE_NO_DONE, + READ_VPN_DETAIL_TYPE_BROKEN, +} ReadVpnDetailType; + typedef struct { const char *key; const char *val; @@ -2285,6 +2291,7 @@ _do_read_vpn_details_impl1(const char *file, int memfd, char *mem, gsize len, + ReadVpnDetailType detail_type, const ReadVpnDetailData *expected_data, guint expected_data_len, const ReadVpnDetailData *expected_secrets, @@ -2294,10 +2301,27 @@ _do_read_vpn_details_impl1(const char *file, off_t lseeked; gs_unref_hashtable GHashTable *data = NULL; gs_unref_hashtable GHashTable *secrets = NULL; + char ch; + gboolean append_quit; + char read_buf[1024]; + gssize n_read; + gssize i; written = write(memfd, mem, len); g_assert_cmpint(written, ==, (gssize) len); + append_quit = nmtst_get_rand_bool(); + + if (append_quit) { + if (len > 0 && mem[len - 1] != '\n') { + ch = '\n'; + written = write(memfd, &ch, 1); + g_assert_cmpint(written, ==, 1); + } + written = write(memfd, "QUIT", 4); + g_assert_cmpint(written, ==, 4); + } + lseeked = lseek(memfd, 0, SEEK_SET); g_assert_cmpint(lseeked, ==, 0); @@ -2327,13 +2351,14 @@ _do_read_vpn_details_impl1(const char *file, if (nm_streq(_expected[_i].key, _k)) \ break; \ } \ - if (_i >= _expected_len) \ + if (_i >= _expected_len) { \ g_error("%s:%d: hash '%s' contains unexpected data key '%s' with value '%s'", \ file, \ line, \ G_STRINGIFY(hash), \ _k, \ _v); \ + } \ } \ \ for (_i = 0; _i < _expected_len; _i++) { \ @@ -2342,7 +2367,7 @@ _do_read_vpn_details_impl1(const char *file, g_assert(_d->key); \ g_assert(_d->val); \ _v = g_hash_table_lookup(_hash, _d->key); \ - if (!nm_streq0(_v, _d->val)) \ + if (!nm_streq0(_v, _d->val)) { \ g_error("%s:%d: hash '%s' contains data key '%s' with value %s%s%s but we " \ "expected '%s'", \ file, \ @@ -2351,20 +2376,71 @@ _do_read_vpn_details_impl1(const char *file, _d->key, \ NM_PRINT_FMT_QUOTE_STRING(_v), \ _d->val); \ + } \ } \ \ g_assert_cmpint(g_hash_table_size(_hash), ==, _expected_len); \ } \ G_STMT_END + NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER _assert_hash(data, expected_data, expected_data_len); _assert_hash(secrets, expected_secrets, expected_secrets_len); + NM_PRAGMA_WARNING_REENABLE #undef _assert_hash + + n_read = read(memfd, read_buf, sizeof(read_buf)); + + if (0) { + gs_free char *ss = NULL; + + g_print(">>>> n_read=%zd; \"%s\"", + n_read, + n_read > 0 ? ( + ss = nm_utils_buf_utf8safe_escape_cp(read_buf, + n_read, + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL)) + : ""); + } + + g_assert_cmpint(n_read, >=, 0); + g_assert_cmpint(n_read, <, sizeof(read_buf)); + + i = read(memfd, &ch, 1); + g_assert_cmpint(i, ==, 0); + + switch (detail_type) { + case READ_VPN_DETAIL_TYPE_GOOD: + g_assert_cmpint(n_read, >=, 0); + i = 0; + while (i < n_read && NM_IN_SET(read_buf[i], '\n')) + i++; + if (append_quit) + g_assert_cmpmem("QUIT", 4, &read_buf[i], n_read - i); + else + g_assert_cmpint(n_read - i, ==, 0); + break; + case READ_VPN_DETAIL_TYPE_NO_DONE: + g_assert_cmpint(n_read, ==, 0); + break; + case READ_VPN_DETAIL_TYPE_BROKEN: + g_assert_cmpint(n_read, >, 0); + if (append_quit) { + g_assert_cmpint(n_read, >, 4); + g_assert(memmem(&read_buf[i], n_read + i, "QUIT", 4)); + } + break; + default: + g_assert_not_reached(); + break; + } + return TRUE; } #define _do_read_vpn_details_impl0(str, \ + detail_type, \ expected_data, \ expected_data_len, \ expected_secrets, \ @@ -2385,6 +2461,7 @@ _do_read_vpn_details_impl1(const char *file, _memfd, \ "" str "", \ NM_STRLEN(str), \ + (detail_type), \ expected_data, \ expected_data_len, \ expected_secrets, \ @@ -2393,14 +2470,16 @@ _do_read_vpn_details_impl1(const char *file, } \ G_STMT_END -#define _do_read_vpn_details_empty(str) _do_read_vpn_details_impl0(str, NULL, 0, NULL, 0, {}) +#define _do_read_vpn_details_empty(str) \ + _do_read_vpn_details_impl0(str, READ_VPN_DETAIL_TYPE_GOOD, NULL, 0, NULL, 0, {}) -#define _do_read_vpn_details(str, expected_data, expected_secrets, pre_setup_cmd) \ - _do_read_vpn_details_impl0(str, \ - expected_data, \ - G_N_ELEMENTS(expected_data), \ - expected_secrets, \ - G_N_ELEMENTS(expected_secrets), \ +#define _do_read_vpn_details(str, detail_type, expected_data, expected_secrets, pre_setup_cmd) \ + _do_read_vpn_details_impl0(str, \ + detail_type, \ + expected_data, \ + G_N_ELEMENTS(expected_data), \ + expected_secrets, \ + G_N_ELEMENTS(expected_secrets), \ pre_setup_cmd) static void @@ -2426,6 +2505,7 @@ test_nm_vpn_service_plugin_read_vpn_details(void) "DONE\n" "\n" "", + READ_VPN_DETAIL_TYPE_GOOD, READ_VPN_DETAIL_DATA({"some-key", "string"}, {"some-other-key", "val2"}, ), READ_VPN_DETAIL_DATA({"some-secret", "val3"}, ), ); @@ -2433,6 +2513,7 @@ test_nm_vpn_service_plugin_read_vpn_details(void) "DATA_KEY=some-key\n" "DATA_VAL=string\n" "DONE\n", + READ_VPN_DETAIL_TYPE_GOOD, READ_VPN_DETAIL_DATA({"some-key", "string"}, ), READ_VPN_DETAIL_DATA(), ); @@ -2461,6 +2542,7 @@ test_nm_vpn_service_plugin_read_vpn_details(void) "\n" "DONE\n" "", + READ_VPN_DETAIL_TYPE_BROKEN, READ_VPN_DETAIL_DATA({"some-key", "string\ncontinued after a line break"}, ), READ_VPN_DETAIL_DATA({"key names\ncan have\ncontinuations too", "value"}, ), ); @@ -2474,6 +2556,7 @@ test_nm_vpn_service_plugin_read_vpn_details(void) "=continuations too\n" "SECRET_VAL=value\n" "", + READ_VPN_DETAIL_TYPE_NO_DONE, READ_VPN_DETAIL_DATA({"some-key", "string\ncontinued after a line break"}, ), READ_VPN_DETAIL_DATA({"key names\ncan have\ncontinuations too", "value"}, ), ); @@ -2507,6 +2590,7 @@ test_nm_vpn_service_plugin_read_vpn_details(void) "DONE\n" "\n" "", + READ_VPN_DETAIL_TYPE_GOOD, READ_VPN_DETAIL_DATA({"some\nkey-2", "val2"}, {"some-key", "string"}, {"key3\nkey-2", "val3"}, ), @@ -2546,8 +2630,15 @@ test_nm_vpn_service_plugin_read_vpn_details(void) "DONE\n" "\n" "", - READ_VPN_DETAIL_DATA({"some\nkey-2", "val2"}, {"some-key", "string"}, ), - READ_VPN_DETAIL_DATA(), ); + READ_VPN_DETAIL_TYPE_GOOD, + READ_VPN_DETAIL_DATA({"some\nkey-2", "val2"}, + {"some-key", "string"}, + {"key3\nkey-2", "val3"}, ), + READ_VPN_DETAIL_DATA({"some-secret", "val3"}, + {"key-inval", "in\xc1val"}, + {"ke\xc0yx", "inval"}, + {"keyx", ""}, + {"", "val3"}), ); } /*****************************************************************************/ @@ -3049,10 +3140,12 @@ check_dbus_properties: break; p_expected_type++; if (p_expected_type >= &expected_types[G_N_ELEMENTS(expected_types)]) { + NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER g_error("D-Bus type \"%s\" is not implemented (in property %s.%s)", (const char *) mpr->dbus_type, mif->dbus_iface_name, mpr->dbus_property_name); + NM_PRAGMA_WARNING_REENABLE } } @@ -3151,6 +3244,7 @@ check_dbus_properties: break; } if (p_expected_type_2 >= &expected_types[G_N_ELEMENTS(expected_types)]) { + NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER g_error("D-Bus property \"%s.%s\" (type \"%s\") maps to property \"%s\", " "but that has an unexpected property type %s (expected %s)", mif->dbus_iface_name, @@ -3159,6 +3253,7 @@ check_dbus_properties: pspec->name, g_type_name(pspec->value_type), g_type_name(p_expected_type->default_gtype)); + NM_PRAGMA_WARNING_REENABLE } } -- cgit 1.3.0-6-gf8a5