diff options
Diffstat (limited to 'src/libnm-glib-aux')
| -rw-r--r-- | src/libnm-glib-aux/nm-glib.h | 10 | ||||
| -rw-r--r-- | src/libnm-glib-aux/nm-json-aux.h | 5 | ||||
| -rw-r--r-- | src/libnm-glib-aux/nm-logging-fwd.h | 117 | ||||
| -rw-r--r-- | src/libnm-glib-aux/nm-macros-internal.h | 39 | ||||
| -rw-r--r-- | src/libnm-glib-aux/nm-secret-utils.c | 33 | ||||
| -rw-r--r-- | src/libnm-glib-aux/nm-secret-utils.h | 4 | ||||
| -rw-r--r-- | src/libnm-glib-aux/nm-shared-utils.c | 99 | ||||
| -rw-r--r-- | src/libnm-glib-aux/nm-shared-utils.h | 123 | ||||
| -rw-r--r-- | src/libnm-glib-aux/nm-test-utils.h | 14 | ||||
| -rw-r--r-- | src/libnm-glib-aux/nm-time-utils.h | 6 | ||||
| -rw-r--r-- | src/libnm-glib-aux/nm-uuid.c | 70 | ||||
| -rw-r--r-- | src/libnm-glib-aux/nm-value-type.h | 66 | ||||
| -rw-r--r-- | src/libnm-glib-aux/tests/test-shared-general.c | 3 |
13 files changed, 370 insertions, 219 deletions
diff --git a/src/libnm-glib-aux/nm-glib.h b/src/libnm-glib-aux/nm-glib.h index 4ab9cbbd..f3be3b32 100644 --- a/src/libnm-glib-aux/nm-glib.h +++ b/src/libnm-glib-aux/nm-glib.h @@ -717,4 +717,14 @@ _nm_deprecated("Don't use this API") void _nm_forbidden_glib_api_n(gconstpointer /*****************************************************************************/ +/* g_alloca0() evaluates the "size" argument multiple times. That seems an error + * prone API (as it's not function-like). + * + * We could fix it by using an expression statement. But it doesn't seem + * worth it, so hide it to prevent its use. */ +#undef g_alloca0 +#undef g_newa0 + +/*****************************************************************************/ + #endif /* __NM_GLIB_H__ */ diff --git a/src/libnm-glib-aux/nm-json-aux.h b/src/libnm-glib-aux/nm-json-aux.h index 275ed770..3054b1f9 100644 --- a/src/libnm-glib-aux/nm-json-aux.h +++ b/src/libnm-glib-aux/nm-json-aux.h @@ -391,6 +391,7 @@ nm_value_type_to_json(NMValueType value_type, GString *gstr, gconstpointer p_fie nm_json_gstr_append_string(gstr, *((const char *const *) p_field)); return; case NM_VALUE_TYPE_BYTES: + case NM_VALUE_TYPE_STRV: case NM_VALUE_TYPE_NONE: case NM_VALUE_TYPE_UNSPEC: break; @@ -428,12 +429,12 @@ nm_value_type_from_json(const NMJsonVt *vt, return (nm_jansson_json_as_string(vt, elem, out_val) > 0); case NM_VALUE_TYPE_BYTES: + case NM_VALUE_TYPE_STRV: case NM_VALUE_TYPE_NONE: case NM_VALUE_TYPE_UNSPEC: break; } - nm_assert_not_reached(); - return FALSE; + return nm_assert_unreachable_val(FALSE); } #endif /* NM_VALUE_TYPE_DEFINE_FUNCTIONS */ diff --git a/src/libnm-glib-aux/nm-logging-fwd.h b/src/libnm-glib-aux/nm-logging-fwd.h index 3e999c4a..0e715c50 100644 --- a/src/libnm-glib-aux/nm-logging-fwd.h +++ b/src/libnm-glib-aux/nm-logging-fwd.h @@ -9,54 +9,54 @@ /* Log domains */ -typedef enum { /*< skip >*/ - LOGD_NONE = 0LL, - LOGD_PLATFORM = (1LL << 0), /* Platform services */ - LOGD_RFKILL = (1LL << 1), - LOGD_ETHER = (1LL << 2), - LOGD_WIFI = (1LL << 3), - LOGD_BT = (1LL << 4), - LOGD_MB = (1LL << 5), /* mobile broadband */ - LOGD_DHCP4 = (1LL << 6), - LOGD_DHCP6 = (1LL << 7), - LOGD_PPP = (1LL << 8), - LOGD_WIFI_SCAN = (1LL << 9), - LOGD_IP4 = (1LL << 10), - LOGD_IP6 = (1LL << 11), - LOGD_AUTOIP4 = (1LL << 12), - LOGD_DNS = (1LL << 13), - LOGD_VPN = (1LL << 14), - LOGD_SHARING = (1LL << 15), /* Connection sharing/dnsmasq */ - LOGD_SUPPLICANT = (1LL << 16), /* Wi-Fi and 802.1x */ - LOGD_AGENTS = (1LL << 17), /* Secret agents */ - LOGD_SETTINGS = (1LL << 18), /* Settings */ - LOGD_SUSPEND = (1LL << 19), /* Suspend/Resume */ - LOGD_CORE = (1LL << 20), /* Core daemon and policy stuff */ - LOGD_DEVICE = (1LL << 21), /* Device state and activation */ - LOGD_OLPC = (1LL << 22), - LOGD_INFINIBAND = (1LL << 23), - LOGD_FIREWALL = (1LL << 24), - LOGD_ADSL = (1LL << 25), - LOGD_BOND = (1LL << 26), - LOGD_VLAN = (1LL << 27), - LOGD_BRIDGE = (1LL << 28), - LOGD_DBUS_PROPS = (1LL << 29), - LOGD_TEAM = (1LL << 30), - LOGD_CONCHECK = (1LL << 31), - LOGD_DCB = (1LL << 32), /* Data Center Bridging */ - LOGD_DISPATCH = (1LL << 33), - LOGD_AUDIT = (1LL << 34), - LOGD_SYSTEMD = (1LL << 35), - LOGD_VPN_PLUGIN = (1LL << 36), - LOGD_PROXY = (1LL << 37), - - __LOGD_MAX, - LOGD_ALL = (((__LOGD_MAX - 1LL) << 1) - 1LL), - LOGD_DEFAULT = LOGD_ALL & ~(LOGD_DBUS_PROPS | LOGD_WIFI_SCAN | LOGD_VPN_PLUGIN | 0), - - /* aliases: */ - LOGD_DHCP = LOGD_DHCP4 | LOGD_DHCP6, - LOGD_IP = LOGD_IP4 | LOGD_IP6, +typedef enum { + LOGD_NONE = 0LL, + LOGD_PLATFORM = (1LL << 0), /* Platform services */ + LOGD_RFKILL = (1LL << 1), + LOGD_ETHER = (1LL << 2), + LOGD_WIFI = (1LL << 3), + LOGD_BT = (1LL << 4), + LOGD_MB = (1LL << 5), /* mobile broadband */ + LOGD_DHCP4 = (1LL << 6), + LOGD_DHCP6 = (1LL << 7), + LOGD_PPP = (1LL << 8), + LOGD_WIFI_SCAN = (1LL << 9), + LOGD_IP4 = (1LL << 10), + LOGD_IP6 = (1LL << 11), + LOGD_AUTOIP4 = (1LL << 12), + LOGD_DNS = (1LL << 13), + LOGD_VPN = (1LL << 14), + LOGD_SHARING = (1LL << 15), /* Connection sharing/dnsmasq */ + LOGD_SUPPLICANT = (1LL << 16), /* Wi-Fi and 802.1x */ + LOGD_AGENTS = (1LL << 17), /* Secret agents */ + LOGD_SETTINGS = (1LL << 18), /* Settings */ + LOGD_SUSPEND = (1LL << 19), /* Suspend/Resume */ + LOGD_CORE = (1LL << 20), /* Core daemon and policy stuff */ + LOGD_DEVICE = (1LL << 21), /* Device state and activation */ + LOGD_OLPC = (1LL << 22), + LOGD_INFINIBAND = (1LL << 23), + LOGD_FIREWALL = (1LL << 24), + LOGD_ADSL = (1LL << 25), + LOGD_BOND = (1LL << 26), + LOGD_VLAN = (1LL << 27), + LOGD_BRIDGE = (1LL << 28), + LOGD_DBUS_PROPS = (1LL << 29), + LOGD_TEAM = (1LL << 30), + LOGD_CONCHECK = (1LL << 31), + LOGD_DCB = (1LL << 32), /* Data Center Bridging */ + LOGD_DISPATCH = (1LL << 33), + LOGD_AUDIT = (1LL << 34), + LOGD_SYSTEMD = (1LL << 35), + LOGD_VPN_PLUGIN = (1LL << 36), + LOGD_PROXY = (1LL << 37), + + __LOGD_MAX, + LOGD_ALL = (((__LOGD_MAX - 1LL) << 1) - 1LL), + LOGD_DEFAULT = LOGD_ALL & ~(LOGD_DBUS_PROPS | LOGD_WIFI_SCAN | LOGD_VPN_PLUGIN | 0), + + /* aliases: */ + LOGD_DHCP = LOGD_DHCP4 | LOGD_DHCP6, + LOGD_IP = LOGD_IP4 | LOGD_IP6, #define LOGD_DHCPX(is_ipv4) ((is_ipv4) ? LOGD_DHCP4 : LOGD_DHCP6) #define LOGD_IPX(is_ipv4) ((is_ipv4) ? LOGD_IP4 : LOGD_IP6) @@ -64,19 +64,20 @@ typedef enum { /*< skip >*/ } NMLogDomain; /* Log levels */ -typedef enum { /*< skip >*/ - LOGL_TRACE, - LOGL_DEBUG, - LOGL_INFO, - LOGL_WARN, - LOGL_ERR, +typedef enum { - _LOGL_N_REAL, /* the number of actual logging levels */ + LOGL_TRACE, + LOGL_DEBUG, + LOGL_INFO, + LOGL_WARN, + LOGL_ERR, - _LOGL_OFF = _LOGL_N_REAL, /* special logging level that is always disabled. */ - _LOGL_KEEP, /* special logging level to indicate that the logging level should not be changed. */ + _LOGL_N_REAL, /* the number of actual logging levels */ - _LOGL_N, /* the number of logging levels including "OFF" */ + _LOGL_OFF = _LOGL_N_REAL, /* special logging level that is always disabled. */ + _LOGL_KEEP, /* special logging level to indicate that the logging level should not be changed. */ + + _LOGL_N, /* the number of logging levels including "OFF" */ } NMLogLevel; gboolean _nm_log_enabled_impl(gboolean mt_require_locking, NMLogLevel level, NMLogDomain domain); diff --git a/src/libnm-glib-aux/nm-macros-internal.h b/src/libnm-glib-aux/nm-macros-internal.h index 14c16020..7cc8ac97 100644 --- a/src/libnm-glib-aux/nm-macros-internal.h +++ b/src/libnm-glib-aux/nm-macros-internal.h @@ -184,22 +184,31 @@ _nm_auto_freev(gpointer ptr) * same name for the same warning. */ #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define NM_PRAGMA_DIAGNOSTICS_PUSH _Pragma("GCC diagnostic push") #define NM_PRAGMA_WARNING_DISABLE(warning) \ - _Pragma("GCC diagnostic push") _Pragma(_NM_PRAGMA_WARNING_DO(warning)) + NM_PRAGMA_DIAGNOSTICS_PUSH _Pragma(_NM_PRAGMA_WARNING_DO(warning)) +#define NM_PRAGMA_WARNING_REENABLE _Pragma("GCC diagnostic pop") #elif defined(__clang__) -#define NM_PRAGMA_WARNING_DISABLE(warning) \ - _Pragma("clang diagnostic push") _Pragma(_NM_PRAGMA_WARNING_DO("-Wunknown-warning-option")) \ +#define NM_PRAGMA_DIAGNOSTICS_PUSH _Pragma("clang diagnostic push") +#define NM_PRAGMA_WARNING_DISABLE(warning) \ + NM_PRAGMA_DIAGNOSTICS_PUSH _Pragma(_NM_PRAGMA_WARNING_DO("-Wunknown-warning-option")) \ _Pragma(_NM_PRAGMA_WARNING_DO(warning)) +#define NM_PRAGMA_WARNING_REENABLE _Pragma("clang diagnostic pop") #else +#define NM_PRAGMA_DIAGNOSTICS_PUSH #define NM_PRAGMA_WARNING_DISABLE(warning) +#define NM_PRAGMA_WARNING_REENABLE #endif -#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -#define NM_PRAGMA_WARNING_REENABLE _Pragma("GCC diagnostic pop") -#elif defined(__clang__) -#define NM_PRAGMA_WARNING_REENABLE _Pragma("clang diagnostic pop") +/*****************************************************************************/ + +/* Seems gcc-12 has a tendency for false-positive -Wdangling-pointer warnings with + * g_error()'s `for(;;);`. See https://bugzilla.redhat.com/show_bug.cgi?id=2056613 . + * Work around, but only for the affected gcc 12.0.1. */ +#if defined(__GNUC__) && __GNUC__ == 12 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ <= 1 +#define NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER NM_PRAGMA_WARNING_DISABLE("-Wdangling-pointer") #else -#define NM_PRAGMA_WARNING_REENABLE +#define NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER NM_PRAGMA_DIAGNOSTICS_PUSH #endif /*****************************************************************************/ @@ -611,10 +620,16 @@ nm_str_realloc(char *str) /* invokes _notify() for all arguments (of type _PropertyEnums). Note, that if * there are more than one prop arguments, this will involve a freeze/thaw * of GObject property notifications. */ -#define nm_gobject_notify_together_full(suffix, obj, ...) \ - _nm_gobject_notify_together_impl##suffix(obj, \ - NM_NARG(__VA_ARGS__), \ - (const _PropertyEnums##suffix[]){__VA_ARGS__}) +#define nm_gobject_notify_together_full(suffix, obj, ...) \ + G_STMT_START \ + { \ + const _PropertyEnums##suffix _props[] = {__VA_ARGS__}; \ + \ + G_STATIC_ASSERT(G_N_ELEMENTS(_props) == NM_NARG(__VA_ARGS__)); \ + \ + _nm_gobject_notify_together_impl##suffix(obj, G_N_ELEMENTS(_props), _props); \ + } \ + G_STMT_END #define nm_gobject_notify_together(obj, ...) nm_gobject_notify_together_full(, obj, __VA_ARGS__) diff --git a/src/libnm-glib-aux/nm-secret-utils.c b/src/libnm-glib-aux/nm-secret-utils.c index c764b6e5..983b04ca 100644 --- a/src/libnm-glib-aux/nm-secret-utils.c +++ b/src/libnm-glib-aux/nm-secret-utils.c @@ -10,6 +10,8 @@ #include <malloc.h> +#include "nm-io-utils.h" + /*****************************************************************************/ void @@ -176,3 +178,34 @@ nm_utils_memeqzero_secret(gconstpointer data, gsize length) } return 1 & ((acc - 1) >> 8); } + +/*****************************************************************************/ + +gboolean +nm_utils_read_crypto_file(const char *filename, NMSecretPtr *out_contents, GError **error) +{ + nm_assert(out_contents); + nm_assert(out_contents->len == 0); + nm_assert(!out_contents->str); + + return nm_utils_file_get_contents(-1, + filename, + 100 * 1024 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET, + &out_contents->str, + &out_contents->len, + NULL, + error); +} + +GBytes * +nm_utils_read_crypto_file_to_bytes(const char *filename, GError **error) +{ + nm_auto_clear_secret_ptr NMSecretPtr contents = {0}; + + g_return_val_if_fail(filename, NULL); + + if (!nm_utils_read_crypto_file(filename, &contents, error)) + return NULL; + return nm_secret_copy_to_gbytes(contents.bin, contents.len); +} diff --git a/src/libnm-glib-aux/nm-secret-utils.h b/src/libnm-glib-aux/nm-secret-utils.h index 513dbca5..c175bc8f 100644 --- a/src/libnm-glib-aux/nm-secret-utils.h +++ b/src/libnm-glib-aux/nm-secret-utils.h @@ -286,4 +286,8 @@ nm_secret_mem_try_realloc_take(gpointer m_old, gboolean do_bzero_mem, gsize cur_ /*****************************************************************************/ +gboolean nm_utils_read_crypto_file(const char *filename, NMSecretPtr *out_contents, GError **error); + +GBytes *nm_utils_read_crypto_file_to_bytes(const char *filename, GError **error); + #endif /* __NM_SECRET_UTILS_H__ */ diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index 563b7cc2..ad99a6b9 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -870,7 +870,12 @@ nm_utils_to_string_buffer_init(char **buf, gsize *len) { if (!*buf) { *buf = _nm_utils_to_string_buffer; - *len = sizeof(_nm_utils_to_string_buffer); + *len = NM_UTILS_TO_STRING_BUFFER_SIZE; + + /* We no longer want to support callers to omit the buffer + * and fallback to the global buffer. Callers should be fixed + * to always provide a valid buffer. */ + g_return_if_reached(); } } @@ -945,20 +950,6 @@ nm_utils_flags2str(const NMUtilsFlags2StrDesc *descs, /*****************************************************************************/ -/** - * _nm_utils_ip4_prefix_to_netmask: - * @prefix: a CIDR prefix - * - * Returns: the netmask represented by the prefix, in network byte order - **/ -guint32 -_nm_utils_ip4_prefix_to_netmask(guint32 prefix) -{ - return prefix < 32 ? ~htonl(0xFFFFFFFFu >> prefix) : 0xFFFFFFFFu; -} - -/*****************************************************************************/ - guint32 _nm_utils_ip4_get_default_prefix0(in_addr_t ip) { @@ -1130,6 +1121,7 @@ nm_utils_parse_inaddr_bin_full(int addr_family, #if NM_MORE_ASSERTS > 10 if (addr_family == AF_INET) { + NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER gs_free_error GError *error = NULL; in_addr_t a; @@ -1145,6 +1137,7 @@ nm_utils_parse_inaddr_bin_full(int addr_family, error->message); } nm_assert(addrbin.addr4 == a); + NM_PRAGMA_WARNING_REENABLE } #endif @@ -2958,8 +2951,8 @@ _str_buf_append_c_escape_octal(NMStrBuf *strbuf, char ch) * * Returns: the unescaped buffer of length @out_len. If @str is %NULL, this returns %NULL * and sets @out_len to 0. Otherwise, a non-%NULL binary buffer is returned with - * @out_len bytes. Note that the binary buffer is guaranteed to be NUL terminated. That - * is @result[@out_len] is NUL. + * @out_len bytes. Note that the binary buffer is guaranteed to be NUL terminated + * (@result[@out_len] is NUL). * Note that the result is binary, and may have embedded NUL characters and non-UTF-8. * If the function can avoid cloning the input string, it will return a pointer inside * the input @str. For example, if there is no backslash, no cloning is necessary. In that @@ -3121,11 +3114,14 @@ nm_utils_buf_utf8safe_unescape(const char *str, * invalid UTF-8 sequences, and other (depending on @flags). * * Returns: the escaped input buffer, as valid UTF-8. If no escaping - * is necessary, it returns the input @buf. Otherwise, an allocated - * string @to_free is returned which must be freed by the caller - * with g_free. The escaping can be reverted by g_strcompress(). - * There are cases where this function can return NULL: - * - if @buflen is 0 + * is necessary and @buflen is negative, it returns the input @buf + * that can be interpreted as NUL terminated UTF-8 string. + * Otherwise, an allocated string @to_free is returned which must be freed + * by the caller with g_free(). + * The escaping can be reverted by nm_utils_buf_utf8safe_unescape() + * (or, if in the absence of NUL characters, with g_strcompress()). + * There are cases where this function returns %NULL: + * - if @buflen is 0. * - if @buflen is negative and @buf is NULL. **/ const char * @@ -4689,14 +4685,20 @@ _nm_utils_invoke_on_idle_start(gboolean use_timeout, } if (use_timeout) { + /* We use G_PRIORITY_DEFAULT_IDLE both for the with/without timeout + * case. The reason is not strong, but it seems right that the caller + * requests a lower priority than G_PRIORITY_DEFAULT. That is unlike + * what g_timeout_add() would do. */ source = nm_g_timeout_source_new(timeout_msec, - G_PRIORITY_DEFAULT, + G_PRIORITY_DEFAULT_IDLE, _nm_utils_invoke_on_idle_cb_idle, data, NULL); } else { - source = - nm_g_idle_source_new(G_PRIORITY_DEFAULT, _nm_utils_invoke_on_idle_cb_idle, data, NULL); + source = nm_g_idle_source_new(G_PRIORITY_DEFAULT_IDLE, + _nm_utils_invoke_on_idle_cb_idle, + data, + NULL); } /* use the current thread default context. */ @@ -4840,6 +4842,27 @@ nm_utils_bin2hexstr_full(gconstpointer addr, return out0; } +char * +_nm_utils_bin2hexstr(gconstpointer src, gsize len, int final_len) +{ + char *result; + gsize buflen = (len * 2) + 1; + + nm_assert(src); + nm_assert(len > 0 && (buflen - 1) / 2 == len); + nm_assert(final_len < 0 || (gsize) final_len < buflen); + + result = g_malloc(buflen); + + nm_utils_bin2hexstr_full(src, len, '\0', FALSE, result); + + /* Cut converted key off at the correct length for this cipher type */ + if (final_len >= 0 && (gsize) final_len < buflen) + result[final_len] = '\0'; + + return result; +} + guint8 * nm_utils_hexstr2bin_full(const char *hexstr, gboolean allow_0x_prefix, @@ -6259,7 +6282,7 @@ _nm_utils_ssid_to_string_gbytes(GBytes *ssid) /*****************************************************************************/ gconstpointer -nm_utils_ipx_address_clear_host_address(int family, gpointer dst, gconstpointer src, guint8 plen) +nm_utils_ipx_address_clear_host_address(int family, gpointer dst, gconstpointer src, guint32 plen) { g_return_val_if_fail(dst, NULL); @@ -6283,21 +6306,10 @@ nm_utils_ipx_address_clear_host_address(int family, gpointer dst, gconstpointer return dst; } -/* nm_utils_ip4_address_clear_host_address: - * @addr: source ip6 address - * @plen: prefix length of network - * - * returns: the input address, with the host address set to 0. - */ -in_addr_t -nm_utils_ip4_address_clear_host_address(in_addr_t addr, guint8 plen) -{ - return addr & _nm_utils_ip4_prefix_to_netmask(plen); -} - /* nm_utils_ip6_address_clear_host_address: * @dst: destination output buffer, will contain the network part of the @src address - * @src: source ip6 address + * @src: source ip6 address. If NULL, this does an in-place update of @dst. + * Also, @src and @dst are allowed to be the same pointers. * @plen: prefix length of network * * Note: this function is self assignment safe, to update @src inplace, set both @@ -6306,7 +6318,7 @@ nm_utils_ip4_address_clear_host_address(in_addr_t addr, guint8 plen) const struct in6_addr * nm_utils_ip6_address_clear_host_address(struct in6_addr *dst, const struct in6_addr *src, - guint8 plen) + guint32 plen) { g_return_val_if_fail(plen <= 128, NULL); g_return_val_if_fail(dst, NULL); @@ -6335,14 +6347,15 @@ nm_utils_ip6_address_clear_host_address(struct in6_addr *dst, int nm_utils_ip6_address_same_prefix_cmp(const struct in6_addr *addr_a, const struct in6_addr *addr_b, - guint8 plen) + guint32 plen) { int nbytes; guint8 va, vb, m; - if (plen >= 128) + if (plen >= 128) { + nm_assert(plen == 128); NM_CMP_DIRECT_MEMCMP(addr_a, addr_b, sizeof(struct in6_addr)); - else { + } else { nbytes = plen / 8; if (nbytes) NM_CMP_DIRECT_MEMCMP(addr_a, addr_b, nbytes); diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index a953140b..941312bd 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -389,15 +389,43 @@ gboolean nm_utils_get_ipv6_interface_identifier(NMLinkType link_type, /*****************************************************************************/ +/** + * _nm_utils_ip4_prefix_to_netmask: + * @prefix: a CIDR prefix + * + * Returns: the netmask represented by the prefix, in network byte order + **/ +static inline in_addr_t +_nm_utils_ip4_prefix_to_netmask(guint32 prefix) +{ + nm_assert(prefix <= 32); + return prefix < 32 ? ~htonl(0xFFFFFFFFu >> prefix) : 0xFFFFFFFFu; +} + +guint32 _nm_utils_ip4_get_default_prefix0(in_addr_t ip); +guint32 _nm_utils_ip4_get_default_prefix(in_addr_t ip); + gconstpointer -nm_utils_ipx_address_clear_host_address(int family, gpointer dst, gconstpointer src, guint8 plen); -in_addr_t nm_utils_ip4_address_clear_host_address(in_addr_t addr, guint8 plen); +nm_utils_ipx_address_clear_host_address(int family, gpointer dst, gconstpointer src, guint32 plen); + +/* nm_utils_ip4_address_clear_host_address: + * @addr: source ip6 address + * @plen: prefix length of network + * + * returns: the input address, with the host address set to 0. + */ +static inline in_addr_t +nm_utils_ip4_address_clear_host_address(in_addr_t addr, guint32 plen) +{ + return addr & _nm_utils_ip4_prefix_to_netmask(plen); +} + const struct in6_addr *nm_utils_ip6_address_clear_host_address(struct in6_addr *dst, const struct in6_addr *src, - guint8 plen); + guint32 plen); static inline int -nm_utils_ip4_address_same_prefix_cmp(in_addr_t addr_a, in_addr_t addr_b, guint8 plen) +nm_utils_ip4_address_same_prefix_cmp(in_addr_t addr_a, in_addr_t addr_b, guint32 plen) { NM_CMP_DIRECT(htonl(nm_utils_ip4_address_clear_host_address(addr_a, plen)), htonl(nm_utils_ip4_address_clear_host_address(addr_b, plen))); @@ -406,7 +434,21 @@ nm_utils_ip4_address_same_prefix_cmp(in_addr_t addr_a, in_addr_t addr_b, guint8 int nm_utils_ip6_address_same_prefix_cmp(const struct in6_addr *addr_a, const struct in6_addr *addr_b, - guint8 plen); + guint32 plen); + +static inline gboolean +nm_utils_ip4_address_same_prefix(in_addr_t addr_a, in_addr_t addr_b, guint32 plen) +{ + return nm_utils_ip4_address_same_prefix_cmp(addr_a, addr_b, plen) == 0; +} + +static inline gboolean +nm_utils_ip6_address_same_prefix(const struct in6_addr *addr_a, + const struct in6_addr *addr_b, + guint8 plen) +{ + return nm_utils_ip6_address_same_prefix_cmp(addr_a, addr_b, plen) == 0; +} static inline int nm_utils_ip_address_same_prefix_cmp(int addr_family, @@ -414,8 +456,6 @@ nm_utils_ip_address_same_prefix_cmp(int addr_family, gconstpointer addr_b, guint8 plen) { - nm_assert_addr_family(addr_family); - NM_CMP_SELF(addr_a, addr_b); if (NM_IS_IPv4(addr_family)) { @@ -428,20 +468,6 @@ nm_utils_ip_address_same_prefix_cmp(int addr_family, } static inline gboolean -nm_utils_ip4_address_same_prefix(in_addr_t addr_a, in_addr_t addr_b, guint8 plen) -{ - return nm_utils_ip4_address_same_prefix_cmp(addr_a, addr_b, plen) == 0; -} - -static inline gboolean -nm_utils_ip6_address_same_prefix(const struct in6_addr *addr_a, - const struct in6_addr *addr_b, - guint8 plen) -{ - return nm_utils_ip6_address_same_prefix_cmp(addr_a, addr_b, plen) == 0; -} - -static inline gboolean nm_utils_ip_address_same_prefix(int addr_family, gconstpointer addr_a, gconstpointer addr_b, @@ -458,6 +484,10 @@ nm_utils_ip_address_same_prefix(int addr_family, /*****************************************************************************/ +gboolean nm_utils_ip_is_site_local(int addr_family, const void *address); + +/*****************************************************************************/ + #define NM_IPV4LL_NETWORK ((in_addr_t) (htonl(0xA9FE0000lu))) #define NM_IPV4LL_NETMASK ((in_addr_t) (htonl(0xFFFF0000lu))) @@ -974,24 +1004,6 @@ nm_utils_escaped_tokens_options_escape_val(const char *val, char **out_to_free) /*****************************************************************************/ -guint32 _nm_utils_ip4_prefix_to_netmask(guint32 prefix); -guint32 _nm_utils_ip4_get_default_prefix0(in_addr_t ip); -guint32 _nm_utils_ip4_get_default_prefix(in_addr_t ip); - -gconstpointer -nm_utils_ipx_address_clear_host_address(int family, gpointer dst, gconstpointer src, guint8 plen); -in_addr_t nm_utils_ip4_address_clear_host_address(in_addr_t addr, guint8 plen); -const struct in6_addr *nm_utils_ip6_address_clear_host_address(struct in6_addr *dst, - const struct in6_addr *src, - guint8 plen); -int nm_utils_ip6_address_same_prefix_cmp(const struct in6_addr *addr_a, - const struct in6_addr *addr_b, - guint8 plen); - -gboolean nm_utils_ip_is_site_local(int addr_family, const void *address); - -/*****************************************************************************/ - gboolean nm_utils_parse_inaddr_bin_full(int addr_family, gboolean accept_legacy, const char *text, @@ -1047,7 +1059,9 @@ int _nm_utils_ascii_str_to_bool(const char *str, int default_value); /*****************************************************************************/ -extern _nm_thread_local char _nm_utils_to_string_buffer[2096]; +#define NM_UTILS_TO_STRING_BUFFER_SIZE 2096 + +extern _nm_thread_local char _nm_utils_to_string_buffer[NM_UTILS_TO_STRING_BUFFER_SIZE]; void nm_utils_to_string_buffer_init(char **buf, gsize *len); gboolean nm_utils_to_string_buffer_init_null(gconstpointer obj, char **buf, gsize *len); @@ -2710,6 +2724,8 @@ char *nm_utils_bin2hexstr_full(gconstpointer addr, gboolean upper_case, char *out); +char *_nm_utils_bin2hexstr(gconstpointer src, gsize len, int final_len); + #define nm_utils_bin2hexstr_a(addr, length, delimiter, upper_case, str_to_free) \ ({ \ gconstpointer _addr = (addr); \ @@ -3141,6 +3157,33 @@ nm_strvarray_remove_first(GArray *strv, const char *needle) return TRUE; } +static inline int +nm_strvarray_cmp(const GArray *a, const GArray *b) +{ + NM_CMP_SELF(a, b); + + return nm_strv_cmp_n((const char *const *) a->data, + a->len, + (const char *const *) b->data, + b->len); +} + +#define nm_strvarray_equal(a, b) (nm_strvarray_cmp((a), (b)) == 0) + +static inline int +_nm_strvarray_cmp_strv(const GArray *strv, const char *const *ss, gsize ss_len) +{ + return nm_strv_cmp_n(strv ? (const char *const *) strv->data : NULL, + strv ? ((gssize) strv->len) : -1, + ss, + ss_len); +} +#define nm_strvarray_cmp_strv(strv, ss, ss_len) \ + _nm_strvarray_cmp_strv((strv), NM_CAST_STRV_CC(ss), (ss_len)) + +#define nm_strvarray_equal_strv(strv, ss, ss_len) \ + (nm_strvarray_cmp_strv((strv), (ss), (ss_len)) == 0) + /*****************************************************************************/ struct _NMVariantAttributeSpec { diff --git a/src/libnm-glib-aux/nm-test-utils.h b/src/libnm-glib-aux/nm-test-utils.h index caf43d5f..2dfe9e32 100644 --- a/src/libnm-glib-aux/nm-test-utils.h +++ b/src/libnm-glib-aux/nm-test-utils.h @@ -1714,8 +1714,11 @@ __nmtst_spawn_sync(const char *working_directory, standard_err, &exit_status, &error); - if (!success) + if (!success) { + NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER g_error("nmtst_spawn_sync(%s): %s", ((char **) argv->pdata)[0], error->message); + NM_PRAGMA_WARNING_REENABLE + } g_assert(!error); g_assert(!standard_out || *standard_out); @@ -1844,7 +1847,8 @@ _nmtst_assert_resolve_relative_path_equals(const char *f1, /* Fixme: later we might need to coalesce repeated '/', "./", and "../". * For now, it's good enough. */ - if (g_strcmp0(p1, p2) != 0) + if (g_strcmp0(p1, p2) != 0) { + NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER g_error("%s:%d : filenames don't match \"%s\" vs. \"%s\" // \"%s\" - \"%s\"", file, line, @@ -1852,6 +1856,8 @@ _nmtst_assert_resolve_relative_path_equals(const char *f1, f2, p1, p2); + NM_PRAGMA_WARNING_REENABLE + } } #define nmtst_assert_resolve_relative_path_equals(f1, f2) \ _nmtst_assert_resolve_relative_path_equals(f1, f2, __FILE__, __LINE__); @@ -2404,9 +2410,11 @@ _nmtst_assert_connection_has_settings(NMConnection *connection, settings = nm_connection_get_settings(connection, &len); for (i = 0; i < len; i++) { if (!g_hash_table_remove(names, nm_setting_get_name(settings[i])) && has_at_most) { + NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER g_error( "nmtst_assert_connection_has_settings(): has setting \"%s\" which is not expected", nm_setting_get_name(settings[i])); + NM_PRAGMA_WARNING_REENABLE } } if (g_hash_table_size(names) > 0 && has_at_least) { @@ -2419,11 +2427,13 @@ _nmtst_assert_connection_has_settings(NMConnection *connection, settings_names[i] = nm_setting_get_name(settings[i]); has_str = g_strjoinv(" ", (char **) settings_names); + NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER g_error("nmtst_assert_connection_has_settings(): the setting lacks %u expected settings " "(expected: [%s] vs. has: [%s])", g_hash_table_size(names), expected_str, has_str); + NM_PRAGMA_WARNING_REENABLE } } #define nmtst_assert_connection_has_settings(connection, ...) \ diff --git a/src/libnm-glib-aux/nm-time-utils.h b/src/libnm-glib-aux/nm-time-utils.h index 3c3e935f..461d6845 100644 --- a/src/libnm-glib-aux/nm-time-utils.h +++ b/src/libnm-glib-aux/nm-time-utils.h @@ -41,6 +41,12 @@ nm_utils_get_monotonic_timestamp_msec_cached(gint64 *cache_now) return (*cache_now) ?: (*cache_now = nm_utils_get_monotonic_timestamp_msec()); } +static inline gint32 +nm_utils_get_monotonic_timestamp_sec_cached(gint32 *cache_now) +{ + return (*cache_now) ?: (*cache_now = nm_utils_get_monotonic_timestamp_sec()); +} + gint64 nm_utils_clock_gettime_nsec(clockid_t clockid); gint64 nm_utils_clock_gettime_msec(clockid_t clockid); diff --git a/src/libnm-glib-aux/nm-uuid.c b/src/libnm-glib-aux/nm-uuid.c index 19b09667..ff0649d0 100644 --- a/src/libnm-glib-aux/nm-uuid.c +++ b/src/libnm-glib-aux/nm-uuid.c @@ -316,8 +316,20 @@ nm_uuid_generate_from_string(NMUuid *uuid, NMUuidType uuid_type, const NMUuid *type_args) { - g_return_val_if_fail(uuid, FALSE); - g_return_val_if_fail(slen == 0 || s, FALSE); + nm_auto_free_checksum GChecksum *sum = NULL; + union { + guint8 sha1[NM_UTILS_CHECKSUM_LENGTH_SHA1]; + guint8 md5[NM_UTILS_CHECKSUM_LENGTH_MD5]; + NMUuid uuid; + } digest; + gsize digest_len; + GChecksumType checksum_type; + + G_STATIC_ASSERT_EXPR(sizeof(digest.md5) >= sizeof(digest.uuid)); + G_STATIC_ASSERT_EXPR(sizeof(digest.sha1) >= sizeof(digest.uuid)); + + g_return_val_if_fail(uuid, NULL); + g_return_val_if_fail(slen <= 0 || s, NULL); if (slen < 0) slen = s ? strlen(s) : 0; @@ -325,43 +337,41 @@ nm_uuid_generate_from_string(NMUuid *uuid, switch (uuid_type) { case NM_UUID_TYPE_LEGACY: nm_assert(!type_args); - nm_crypto_md5_hash(NULL, 0, (guint8 *) s, slen, (guint8 *) uuid, sizeof(*uuid)); + type_args = NULL; + checksum_type = G_CHECKSUM_MD5; break; case NM_UUID_TYPE_VERSION3: + if (!type_args) + type_args = &nm_uuid_ns_zero; + checksum_type = G_CHECKSUM_MD5; + break; case NM_UUID_TYPE_VERSION5: - { if (!type_args) type_args = &nm_uuid_ns_zero; + checksum_type = G_CHECKSUM_SHA1; + break; + default: + g_return_val_if_reached(NULL); + } - if (uuid_type == NM_UUID_TYPE_VERSION3) { - nm_crypto_md5_hash((guint8 *) s, - slen, - (guint8 *) type_args, - sizeof(*type_args), - (guint8 *) uuid, - sizeof(*uuid)); - } else { - nm_auto_free_checksum GChecksum *sum = NULL; - union { - guint8 sha1[NM_UTILS_CHECKSUM_LENGTH_SHA1]; - NMUuid uuid; - } digest; - - sum = g_checksum_new(G_CHECKSUM_SHA1); - g_checksum_update(sum, (guchar *) type_args, sizeof(*type_args)); - g_checksum_update(sum, (guchar *) s, slen); - nm_utils_checksum_get_digest(sum, digest.sha1); - - G_STATIC_ASSERT_EXPR(sizeof(digest.sha1) > sizeof(digest.uuid)); - *uuid = digest.uuid; - } + sum = g_checksum_new(checksum_type); + if (type_args) + g_checksum_update(sum, (guchar *) type_args, sizeof(*type_args)); + g_checksum_update(sum, (guchar *) s, slen); + + digest_len = sizeof(digest); + g_checksum_get_digest(sum, (guint8 *) &digest, &digest_len); + + nm_assert(digest_len >= sizeof(digest.uuid)); + nm_assert(digest_len + == ((checksum_type == G_CHECKSUM_MD5 ? NM_UTILS_CHECKSUM_LENGTH_MD5 + : NM_UTILS_CHECKSUM_LENGTH_SHA1))); + + *uuid = digest.uuid; + if (uuid_type != NM_UUID_TYPE_LEGACY) { uuid->uuid[6] = (uuid->uuid[6] & 0x0F) | (uuid_type << 4); uuid->uuid[8] = (uuid->uuid[8] & 0x3F) | 0x80; - break; - } - default: - g_return_val_if_reached(NULL); } return uuid; diff --git a/src/libnm-glib-aux/nm-value-type.h b/src/libnm-glib-aux/nm-value-type.h index d774e120..771021da 100644 --- a/src/libnm-glib-aux/nm-value-type.h +++ b/src/libnm-glib-aux/nm-value-type.h @@ -9,25 +9,26 @@ typedef enum _nm_packed { NM_VALUE_TYPE_NONE = 0, NM_VALUE_TYPE_UNSPEC = 1, - NM_VALUE_TYPE_BOOL = 2, - NM_VALUE_TYPE_INT32 = 3, - NM_VALUE_TYPE_INT = 4, - NM_VALUE_TYPE_INT64 = 5, - NM_VALUE_TYPE_UINT32 = 6, - NM_VALUE_TYPE_UINT = 7, - NM_VALUE_TYPE_UINT64 = 8, + + NM_VALUE_TYPE_BOOL, + NM_VALUE_TYPE_INT32, + NM_VALUE_TYPE_INT, + NM_VALUE_TYPE_INT64, + NM_VALUE_TYPE_UINT32, + NM_VALUE_TYPE_UINT, + NM_VALUE_TYPE_UINT64, /* Flags are for G_TYPE_FLAGS. That is, internally they are tracked * as a guint, they have a g_param_spec_flags() property and they are * serialized on D-Bus as "u". */ - NM_VALUE_TYPE_FLAGS = 9, + NM_VALUE_TYPE_FLAGS, /* G_TYPE_ENUM */ - NM_VALUE_TYPE_ENUM = 10, - - NM_VALUE_TYPE_STRING = 11, + NM_VALUE_TYPE_ENUM, - NM_VALUE_TYPE_BYTES = 12, + NM_VALUE_TYPE_STRING, + NM_VALUE_TYPE_BYTES, + NM_VALUE_TYPE_STRV, } NMValueType; /*****************************************************************************/ @@ -112,14 +113,17 @@ nm_value_type_cmp(NMValueType value_type, gconstpointer p_a, gconstpointer p_b) return 0; case NM_VALUE_TYPE_STRING: return nm_strcmp0(*((const char *const *) p_a), *((const char *const *) p_b)); + case NM_VALUE_TYPE_BYTES: - return nm_g_bytes_equal0(*((const GBytes *const *) p_a), *((const GBytes *const *) p_b)); + case NM_VALUE_TYPE_STRV: + /* These types have implementation define memory representations. */ + break; + case NM_VALUE_TYPE_NONE: case NM_VALUE_TYPE_UNSPEC: break; } - nm_assert_not_reached(); - return 0; + return nm_assert_unreachable_val(0); } static inline gboolean @@ -163,14 +167,12 @@ nm_value_type_copy(NMValueType value_type, gpointer dst, gconstpointer src) *((char **) dst) = g_strdup(*((const char *const *) src)); } return; + case NM_VALUE_TYPE_BYTES: - /* self assignment safe! */ - if (*((GBytes **) dst) != *((const GBytes *const *) src)) { - _nm_unused gs_unref_bytes GBytes *old = *((GBytes **) dst); + case NM_VALUE_TYPE_STRV: + /* These types have implementation define memory representations. */ + break; - *((GBytes **) dst) = g_bytes_ref(*((GBytes *const *) src)); - } - return; case NM_VALUE_TYPE_NONE: case NM_VALUE_TYPE_UNSPEC: break; @@ -212,14 +214,18 @@ nm_value_type_get_from_variant(NMValueType value_type, return; case NM_VALUE_TYPE_BYTES: + case NM_VALUE_TYPE_STRV: + /* These types have implementation define memory representations. */ + break; + case NM_VALUE_TYPE_INT: case NM_VALUE_TYPE_UINT: case NM_VALUE_TYPE_ENUM: case NM_VALUE_TYPE_FLAGS: /* These types don't have a defined variant type, because it's not * clear how many bits we would need or how to handle the type. */ + break; - /* fall-through */ case NM_VALUE_TYPE_NONE: case NM_VALUE_TYPE_UNSPEC: break; @@ -230,8 +236,7 @@ nm_value_type_get_from_variant(NMValueType value_type, static inline GVariant * nm_value_type_to_variant(NMValueType value_type, gconstpointer src) { - const char *v_string; - const GBytes *v_bytes; + const char *v_string; switch (value_type) { case NM_VALUE_TYPE_BOOL: @@ -247,9 +252,11 @@ nm_value_type_to_variant(NMValueType value_type, gconstpointer src) case NM_VALUE_TYPE_STRING: v_string = *((const char *const *) src); return v_string ? g_variant_new_string(v_string) : NULL; + case NM_VALUE_TYPE_BYTES: - v_bytes = *((const GBytes *const *) src); - return v_bytes ? nm_g_bytes_to_variant_ay(v_bytes) : NULL; + case NM_VALUE_TYPE_STRV: + /* These types have implementation define memory representations. */ + break; case NM_VALUE_TYPE_INT: case NM_VALUE_TYPE_UINT: @@ -257,14 +264,13 @@ nm_value_type_to_variant(NMValueType value_type, gconstpointer src) case NM_VALUE_TYPE_FLAGS: /* These types don't have a defined variant type, because it's not * clear how many bits we would need or how to handle the type. */ + break; - /* fall-through */ case NM_VALUE_TYPE_NONE: case NM_VALUE_TYPE_UNSPEC: break; } - nm_assert_not_reached(); - return NULL; + return nm_assert_unreachable_val(NULL); } static inline const GVariantType * @@ -285,6 +291,8 @@ nm_value_type_get_variant_type(NMValueType value_type) return G_VARIANT_TYPE_STRING; case NM_VALUE_TYPE_BYTES: return G_VARIANT_TYPE_BYTESTRING; + case NM_VALUE_TYPE_STRV: + return G_VARIANT_TYPE_STRING_ARRAY; case NM_VALUE_TYPE_INT: case NM_VALUE_TYPE_UINT: diff --git a/src/libnm-glib-aux/tests/test-shared-general.c b/src/libnm-glib-aux/tests/test-shared-general.c index ecba02e0..46689947 100644 --- a/src/libnm-glib-aux/tests/test-shared-general.c +++ b/src/libnm-glib-aux/tests/test-shared-general.c @@ -283,9 +283,6 @@ test_nm_utils_ip4_prefix_to_netmask(void) g_assert_cmpint(_nm_utils_ip4_prefix_to_netmask(32), ==, nmtst_inet4_from_string("255.255.255.255")); - g_assert_cmpint(_nm_utils_ip4_prefix_to_netmask(33), - ==, - nmtst_inet4_from_string("255.255.255.255")); } /*****************************************************************************/ |