mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-23 08:10:26 +01:00
all/systemd: merge branch 'th/replace-systemd-utils-1'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1191
This commit is contained in:
commit
4930cdd3c8
19 changed files with 1196 additions and 303 deletions
|
|
@ -2329,8 +2329,6 @@ src_libnm_systemd_core_libnm_systemd_core_la_libadd = \
|
|||
|
||||
src_libnm_systemd_core_libnm_systemd_core_la_SOURCES = \
|
||||
src/libnm-systemd-core/nm-default-systemd-core.h \
|
||||
src/libnm-systemd-core/nm-sd-utils-core.c \
|
||||
src/libnm-systemd-core/nm-sd-utils-core.h \
|
||||
src/libnm-systemd-core/nm-sd.c \
|
||||
src/libnm-systemd-core/nm-sd.h \
|
||||
src/libnm-systemd-core/sd-adapt-core/condition.h \
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include "libnm-platform/nm-linux-platform.h"
|
||||
#include "libnm-platform/nm-platform-utils.h"
|
||||
#include "nm-auth-utils.h"
|
||||
#include "libnm-systemd-shared/nm-sd-utils-shared.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -1155,7 +1154,7 @@ nm_utils_file_is_in_path(const char *abs_filename, const char *abs_path)
|
|||
g_return_val_if_fail(abs_filename && abs_filename[0] == '/', NULL);
|
||||
g_return_val_if_fail(abs_path && abs_path[0] == '/', NULL);
|
||||
|
||||
path = nm_sd_utils_path_startswith(abs_filename, abs_path);
|
||||
path = nm_path_startswith(abs_filename, abs_path);
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -1080,7 +1080,7 @@ config_init(NMDhcpClientConfig *config, const NMDhcpClientConfig *src)
|
|||
if (!config->send_hostname) {
|
||||
nm_clear_g_free((gpointer *) &config->hostname);
|
||||
} else if ((config->use_fqdn && !nm_sd_dns_name_is_valid(config->hostname))
|
||||
|| (!config->use_fqdn && !nm_sd_hostname_is_valid(config->hostname, FALSE))) {
|
||||
|| (!config->use_fqdn && !nm_hostname_is_valid(config->hostname, FALSE))) {
|
||||
nm_log_warn(LOGD_DHCP,
|
||||
"dhcp%c: %s '%s' is invalid, will be ignored",
|
||||
nm_utils_addr_family_to_char(config->addr_family),
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "libnm-core-intern/nm-core-internal.h"
|
||||
#include "libnm-glib-aux/nm-str-buf.h"
|
||||
#include "libnm-systemd-shared/nm-sd-utils-shared.h"
|
||||
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "devices/nm-device.h"
|
||||
|
|
@ -2104,7 +2103,7 @@ nm_dns_manager_set_hostname(NMDnsManager *self, const char *hostname, gboolean s
|
|||
domain = hostname;
|
||||
}
|
||||
|
||||
if (!nm_sd_hostname_is_valid(domain, FALSE))
|
||||
if (!nm_hostname_is_valid(domain, FALSE))
|
||||
domain = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include "libnm-glib-aux/nm-secret-utils.h"
|
||||
#include "libnm-glib-aux/nm-time-utils.h"
|
||||
#include "libnm-glib-aux/nm-str-buf.h"
|
||||
#include "libnm-systemd-shared/nm-sd-utils-shared.h"
|
||||
#include "nm-utils.h"
|
||||
#include "libnm-core-intern/nm-core-internal.h"
|
||||
#include "nm-setting-connection.h"
|
||||
|
|
@ -5239,7 +5238,7 @@ nm_utils_shorten_hostname(const char *hostname, char **shortened)
|
|||
nm_assert(hostname);
|
||||
nm_assert(shortened);
|
||||
|
||||
if (nm_sd_hostname_is_valid(hostname, FALSE)) {
|
||||
if (nm_hostname_is_valid(hostname, FALSE)) {
|
||||
*shortened = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -5253,7 +5252,7 @@ nm_utils_shorten_hostname(const char *hostname, char **shortened)
|
|||
|
||||
s = g_strndup(hostname, l);
|
||||
|
||||
if (!nm_sd_hostname_is_valid(s, FALSE)) {
|
||||
if (!nm_hostname_is_valid(s, FALSE)) {
|
||||
*shortened = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@
|
|||
#include "libnm-core-intern/nm-core-internal.h"
|
||||
#include "libnm-core-intern/nm-keyfile-internal.h"
|
||||
|
||||
#include "libnm-systemd-shared/nm-sd-utils-shared.h"
|
||||
|
||||
#include "settings/nm-settings-plugin.h"
|
||||
#include "settings/nm-settings-storage.h"
|
||||
#include "settings/nm-settings-utils.h"
|
||||
|
|
@ -1247,9 +1245,9 @@ nms_keyfile_plugin_init(NMSKeyfilePlugin *plugin)
|
|||
/* dirname_libs are a set of read-only directories with lower priority than /etc or /run.
|
||||
* There is nothing complicated about having multiple of such directories, so dirname_libs
|
||||
* is a list (which currently only has at most one directory). */
|
||||
priv->dirname_libs[0] = nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_LIB));
|
||||
priv->dirname_libs[0] = nm_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_LIB));
|
||||
priv->dirname_libs[1] = NULL;
|
||||
priv->dirname_run = nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_RUN));
|
||||
priv->dirname_run = nm_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_RUN));
|
||||
priv->dirname_etc = nm_config_data_get_value(NM_CONFIG_GET_DATA_ORIG,
|
||||
NM_CONFIG_KEYFILE_GROUP_KEYFILE,
|
||||
NM_CONFIG_KEYFILE_KEY_KEYFILE_PATH,
|
||||
|
|
@ -1262,9 +1260,9 @@ nms_keyfile_plugin_init(NMSKeyfilePlugin *plugin)
|
|||
} else if (!priv->dirname_etc || priv->dirname_etc[0] != '/') {
|
||||
/* either invalid path or unspecified. Use the default. */
|
||||
g_free(priv->dirname_etc);
|
||||
priv->dirname_etc = nm_sd_utils_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_ETC_DEFAULT));
|
||||
priv->dirname_etc = nm_path_simplify(g_strdup(NM_KEYFILE_PATH_NAME_ETC_DEFAULT));
|
||||
} else
|
||||
nm_sd_utils_path_simplify(priv->dirname_etc);
|
||||
nm_path_simplify(priv->dirname_etc);
|
||||
|
||||
/* no duplicates */
|
||||
if (NM_IN_STRSET(priv->dirname_libs[0], priv->dirname_etc, priv->dirname_run))
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
#include "NetworkManagerUtils.h"
|
||||
#include "libnm-core-intern/nm-core-internal.h"
|
||||
#include "nm-core-utils.h"
|
||||
#include "libnm-systemd-core/nm-sd-utils-core.h"
|
||||
|
||||
#include "dns/nm-dns-manager.h"
|
||||
#include "nm-connectivity.h"
|
||||
|
|
@ -2314,7 +2313,6 @@ test_dns_create_resolv_conf(void)
|
|||
static void
|
||||
test_machine_id_read(void)
|
||||
{
|
||||
NMUuid machine_id_sd;
|
||||
const NMUuid *machine_id;
|
||||
char machine_id_str[33];
|
||||
gpointer logstate;
|
||||
|
|
@ -2346,27 +2344,6 @@ test_machine_id_read(void)
|
|||
== machine_id_str);
|
||||
g_assert(strlen(machine_id_str) == 32);
|
||||
g_assert_cmpstr(machine_id_str, ==, nm_utils_machine_id_str());
|
||||
|
||||
/* double check with systemd's implementation... */
|
||||
if (!nm_sd_utils_id128_get_machine(&machine_id_sd)) {
|
||||
/* if systemd failed to read /etc/machine-id, the file likely
|
||||
* is invalid. Our machine-id is fake, and we have nothing to
|
||||
* compare against. */
|
||||
|
||||
if (g_file_test(LOCALSTATEDIR "/lib/dbus/machine-id", G_FILE_TEST_EXISTS)) {
|
||||
/* Hm. So systemd failed to read /etc/machine-id, but we may have the one from D-Bus.
|
||||
* With LOCALSTATEDIR"/lib/dbus/machine-id", we don't really know whether we
|
||||
* parsed that file. Assume we don't know and skip the test on this system. */
|
||||
g_assert(!nm_utils_machine_id_is_fake());
|
||||
return;
|
||||
}
|
||||
|
||||
/* OK, in this case, our function should have generated a random machine ID. */
|
||||
g_assert(nm_utils_machine_id_is_fake());
|
||||
} else {
|
||||
g_assert(!nm_utils_machine_id_is_fake());
|
||||
g_assert_cmpmem(&machine_id_sd, sizeof(NMUuid), machine_id, 16);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -98,141 +98,6 @@ test_sd_event(void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_path_equal(void)
|
||||
{
|
||||
#define _path_equal_check(path, expected) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
const char *_path0 = (path); \
|
||||
const char *_expected = (expected); \
|
||||
gs_free char *_path = g_strdup(_path0); \
|
||||
const char *_path_result; \
|
||||
\
|
||||
_path_result = nm_sd_utils_path_simplify(_path); \
|
||||
g_assert(_path_result == _path); \
|
||||
g_assert_cmpstr(_path, ==, _expected); \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
_path_equal_check("", "");
|
||||
_path_equal_check(".", ".");
|
||||
_path_equal_check("..", "..");
|
||||
_path_equal_check("/..", "/..");
|
||||
_path_equal_check("//..", "/..");
|
||||
_path_equal_check("/.", "/");
|
||||
_path_equal_check("./", ".");
|
||||
_path_equal_check("./.", ".");
|
||||
_path_equal_check(".///.", ".");
|
||||
_path_equal_check(".///./", ".");
|
||||
_path_equal_check(".////", ".");
|
||||
_path_equal_check("//..//foo/", "/../foo");
|
||||
_path_equal_check("///foo//./bar/.", "/foo/bar");
|
||||
_path_equal_check(".//./foo//./bar/.", "foo/bar");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_test_unbase64char(char ch, gboolean maybe_invalid)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = nm_sd_utils_unbase64char(ch, FALSE);
|
||||
|
||||
if (ch == '=') {
|
||||
g_assert(!maybe_invalid);
|
||||
g_assert_cmpint(r, <, 0);
|
||||
g_assert_cmpint(nm_sd_utils_unbase64char(ch, TRUE), ==, G_MAXINT);
|
||||
} else {
|
||||
g_assert_cmpint(r, ==, nm_sd_utils_unbase64char(ch, TRUE));
|
||||
if (r >= 0)
|
||||
g_assert_cmpint(r, <=, 255);
|
||||
if (!maybe_invalid)
|
||||
g_assert_cmpint(r, >=, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_test_unbase64mem_mem(const char *base64, const guint8 *expected_arr, gsize expected_len)
|
||||
{
|
||||
gs_free char *expected_base64 = NULL;
|
||||
int r;
|
||||
nm_auto_free guint8 *exp2_arr = NULL;
|
||||
nm_auto_free guint8 *exp3_arr = NULL;
|
||||
gsize exp2_len;
|
||||
gsize exp3_len;
|
||||
gsize i;
|
||||
|
||||
expected_base64 = g_base64_encode(expected_arr, expected_len);
|
||||
|
||||
for (i = 0; expected_base64[i]; i++)
|
||||
_test_unbase64char(expected_base64[i], FALSE);
|
||||
|
||||
r = nm_sd_utils_unbase64mem(expected_base64,
|
||||
strlen(expected_base64),
|
||||
TRUE,
|
||||
&exp2_arr,
|
||||
&exp2_len);
|
||||
g_assert_cmpint(r, ==, 0);
|
||||
g_assert_cmpmem(expected_arr, expected_len, exp2_arr, exp2_len);
|
||||
|
||||
if (!nm_streq(base64, expected_base64)) {
|
||||
r = nm_sd_utils_unbase64mem(base64, strlen(base64), TRUE, &exp3_arr, &exp3_len);
|
||||
g_assert_cmpint(r, ==, 0);
|
||||
g_assert_cmpmem(expected_arr, expected_len, exp3_arr, exp3_len);
|
||||
}
|
||||
}
|
||||
|
||||
#define _test_unbase64mem(base64, expected_str) \
|
||||
_test_unbase64mem_mem(base64, (const guint8 *) "" expected_str "", NM_STRLEN(expected_str))
|
||||
|
||||
static void
|
||||
_test_unbase64mem_inval(const char *base64)
|
||||
{
|
||||
gs_free guint8 *exp_arr = NULL;
|
||||
gsize exp_len = 0;
|
||||
int r;
|
||||
|
||||
r = nm_sd_utils_unbase64mem(base64, strlen(base64), TRUE, &exp_arr, &exp_len);
|
||||
g_assert_cmpint(r, <, 0);
|
||||
g_assert(!exp_arr);
|
||||
g_assert(exp_len == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nm_sd_utils_unbase64mem(void)
|
||||
{
|
||||
gs_free char *rnd_base64 = NULL;
|
||||
guint8 rnd_buf[30];
|
||||
guint i, rnd_len;
|
||||
|
||||
_test_unbase64mem("", "");
|
||||
_test_unbase64mem(" ", "");
|
||||
_test_unbase64mem(" Y Q == ", "a");
|
||||
_test_unbase64mem(" Y WJjZGV mZ 2g = ", "abcdefgh");
|
||||
_test_unbase64mem_inval(" Y %WJjZGV mZ 2g = ");
|
||||
_test_unbase64mem_inval(" Y %WJjZGV mZ 2g = a");
|
||||
_test_unbase64mem("YQ==", "a");
|
||||
_test_unbase64mem_inval("YQ==a");
|
||||
|
||||
rnd_len = nmtst_get_rand_uint32() % sizeof(rnd_buf);
|
||||
for (i = 0; i < rnd_len; i++)
|
||||
rnd_buf[i] = nmtst_get_rand_uint32() % 256;
|
||||
rnd_base64 = g_base64_encode(rnd_buf, rnd_len);
|
||||
_test_unbase64mem_mem(rnd_base64, rnd_buf, rnd_len);
|
||||
|
||||
_test_unbase64char('=', FALSE);
|
||||
for (i = 0; i < 10; i++) {
|
||||
char ch = nmtst_get_rand_uint32() % 256;
|
||||
|
||||
if (ch != '=')
|
||||
_test_unbase64char(ch, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE();
|
||||
|
||||
int
|
||||
|
|
@ -242,8 +107,6 @@ main(int argc, char **argv)
|
|||
|
||||
g_test_add_func("/systemd/lldp/create", test_lldp_create);
|
||||
g_test_add_func("/systemd/sd-event", test_sd_event);
|
||||
g_test_add_func("/systemd/test_path_equal", test_path_equal);
|
||||
g_test_add_func("/systemd/test_nm_sd_utils_unbase64mem", test_nm_sd_utils_unbase64mem);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
#include "libnm-glib-aux/nm-str-buf.h"
|
||||
#include "libnm-glib-aux/nm-secret-utils.h"
|
||||
#include "libnm-systemd-shared/nm-sd-utils-shared.h"
|
||||
#include "libnm-core-aux-intern/nm-common-macros.h"
|
||||
#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
|
||||
#include "libnm-core-intern/nm-core-internal.h"
|
||||
|
|
@ -4062,7 +4061,7 @@ _write_setting_wireguard(NMSetting *setting, KeyfileWriterInfo *info)
|
|||
|
||||
public_key = nm_wireguard_peer_get_public_key(peer);
|
||||
if (!public_key || !public_key[0]
|
||||
|| !NM_STRCHAR_ALL(public_key, ch, nm_sd_utils_unbase64char(ch, TRUE) >= 0)) {
|
||||
|| !NM_STRCHAR_ALL(public_key, ch, nm_unbase64char(ch) != -EINVAL)) {
|
||||
/* invalid peer. Skip it */
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#include "libnm-glib-aux/nm-enum-utils.h"
|
||||
#include "libnm-glib-aux/nm-time-utils.h"
|
||||
#include "libnm-glib-aux/nm-secret-utils.h"
|
||||
#include "libnm-systemd-shared/nm-sd-utils-shared.h"
|
||||
#include "libnm-core-aux-intern/nm-common-macros.h"
|
||||
#include "nm-utils-private.h"
|
||||
#include "nm-setting-private.h"
|
||||
|
|
@ -5356,7 +5355,7 @@ nm_utils_base64secret_decode(const char *base64_key, gsize required_key_len, gui
|
|||
|
||||
base64_key_len = strlen(base64_key);
|
||||
|
||||
r = nm_sd_utils_unbase64mem(base64_key, base64_key_len, TRUE, &bin_arr, &bin_len);
|
||||
r = nm_unbase64mem_full(base64_key, base64_key_len, TRUE, &bin_arr, &bin_len);
|
||||
if (r < 0)
|
||||
return FALSE;
|
||||
if (bin_len != required_key_len) {
|
||||
|
|
|
|||
|
|
@ -6714,3 +6714,540 @@ nm_g_main_context_can_acquire(GMainContext *context)
|
|||
g_main_context_release(context);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
nm_unbase64char(char c)
|
||||
{
|
||||
/* copied from systemd's unbase64char():
|
||||
* https://github.com/systemd/systemd/blob/688efe7703328c5a0251fafac55757b8864a9f9a/src/basic/hexdecoct.c#L539 */
|
||||
|
||||
switch (c) {
|
||||
case 'A' ... 'Z':
|
||||
return c - 'A';
|
||||
case 'a' ... 'z':
|
||||
return (c - 'a') + ('Z' - 'A' + 1);
|
||||
case '0' ... '9':
|
||||
return (c - '0') + (('Z' - 'A' + 1) + ('z' - 'a' + 1));
|
||||
case '+':
|
||||
return ('Z' - 'A' + 1) + ('z' - 'a' + 1) + ('9' - '0' + 1);
|
||||
case '/':
|
||||
return ('Z' - 'A' + 1) + ('z' - 'a' + 1) + ('9' - '0' + 1) + 1;
|
||||
case '=':
|
||||
/* The padding is a different kind of base64 character. Return
|
||||
* a special error code for it. */
|
||||
return -ERANGE;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
unbase64_next(const char **p, size_t *l)
|
||||
{
|
||||
int ret;
|
||||
|
||||
nm_assert(p);
|
||||
nm_assert(l);
|
||||
|
||||
/* copied from systemd's unbase64_next():
|
||||
* https://github.com/systemd/systemd/blob/688efe7703328c5a0251fafac55757b8864a9f9a/src/basic/hexdecoct.c#L709 */
|
||||
|
||||
/* Find the next non-whitespace character, and decode it. If we find padding, we return it as INT_MAX. We
|
||||
* greedily skip all preceding and all following whitespace. */
|
||||
|
||||
for (;;) {
|
||||
if (*l == 0)
|
||||
return -EPIPE;
|
||||
|
||||
if (!nm_ascii_is_whitespace(**p))
|
||||
break;
|
||||
|
||||
/* Skip leading whitespace */
|
||||
(*p)++;
|
||||
(*l)--;
|
||||
}
|
||||
|
||||
ret = nm_unbase64char(**p);
|
||||
if (ret < 0) {
|
||||
nm_assert(NM_IN_SET(ret, -EINVAL, -ERANGE));
|
||||
if (ret != -ERANGE)
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
(*p)++;
|
||||
(*l)--;
|
||||
|
||||
if (*l == 0)
|
||||
break;
|
||||
if (!nm_ascii_is_whitespace(**p))
|
||||
break;
|
||||
|
||||
/* Skip following whitespace */
|
||||
}
|
||||
|
||||
nm_assert(ret == -ERANGE || ret >= 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_unbase64mem_full:
|
||||
* @p: a valid base64 string. Whitespace is ignored, but invalid encodings
|
||||
* will cause the function to fail.
|
||||
* @l: the length of @p. @p is not treated as NUL terminated string but
|
||||
* merely as a buffer of ascii characters.
|
||||
* @secure: whether the temporary memory will be cleared to avoid leaving
|
||||
* secrets in memory (see also nm_explicit_bzero()).
|
||||
* @mem: (transfer full): the decoded buffer on success.
|
||||
* @len: the length of @mem on success.
|
||||
*
|
||||
* glib provides g_base64_decode(), but that does not report any errors
|
||||
* from invalid encodings. Our own implementation (based on systemd code)
|
||||
* rejects invalid inputs.
|
||||
*
|
||||
* Returns: a non-negative code on success. Invalid encoding let the
|
||||
* function fail.
|
||||
*/
|
||||
int
|
||||
nm_unbase64mem_full(const char *p, gsize l, gboolean secure, guint8 **ret, gsize *ret_size)
|
||||
{
|
||||
gs_free uint8_t *buf = NULL;
|
||||
const char *x;
|
||||
guint8 *z;
|
||||
gsize len;
|
||||
int r;
|
||||
|
||||
/* copied from systemd's unbase64mem_full():
|
||||
* https://github.com/systemd/systemd/blob/688efe7703328c5a0251fafac55757b8864a9f9a/src/basic/hexdecoct.c#L751 */
|
||||
|
||||
nm_assert(p || l == 0);
|
||||
|
||||
if (l == G_MAXSIZE)
|
||||
l = strlen(p);
|
||||
|
||||
/* A group of four input bytes needs three output bytes, in case of padding we need to add two or three extra
|
||||
* bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */
|
||||
len = (l / 4) * 3 + (l % 4 != 0 ? (l % 4) - 1 : 0);
|
||||
|
||||
buf = g_malloc(len + 1);
|
||||
|
||||
for (x = p, z = buf;;) {
|
||||
int a; /* a == 00XXXXXX */
|
||||
int b; /* b == 00YYYYYY */
|
||||
int c; /* c == 00ZZZZZZ */
|
||||
int d; /* d == 00WWWWWW */
|
||||
|
||||
a = unbase64_next(&x, &l);
|
||||
if (a < 0) {
|
||||
if (a == -EPIPE) /* End of string */
|
||||
break;
|
||||
if (a == -ERANGE) { /* Padding is not allowed at the beginning of a 4ch block */
|
||||
r = -EINVAL;
|
||||
goto on_failure;
|
||||
}
|
||||
r = a;
|
||||
goto on_failure;
|
||||
}
|
||||
|
||||
b = unbase64_next(&x, &l);
|
||||
if (b < 0) {
|
||||
if (b == -ERANGE) {
|
||||
/* Padding is not allowed at the second character of a 4ch block either */
|
||||
r = -EINVAL;
|
||||
goto on_failure;
|
||||
}
|
||||
r = b;
|
||||
goto on_failure;
|
||||
}
|
||||
|
||||
c = unbase64_next(&x, &l);
|
||||
if (c < 0) {
|
||||
if (c != -ERANGE) {
|
||||
r = c;
|
||||
goto on_failure;
|
||||
}
|
||||
}
|
||||
|
||||
d = unbase64_next(&x, &l);
|
||||
if (d < 0) {
|
||||
if (d != -ERANGE) {
|
||||
r = d;
|
||||
goto on_failure;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == -ERANGE) { /* Padding at the third character */
|
||||
|
||||
if (d != -ERANGE) { /* If the third character is padding, the fourth must be too */
|
||||
r = -EINVAL;
|
||||
goto on_failure;
|
||||
}
|
||||
|
||||
/* b == 00YY0000 */
|
||||
if (b & 15) {
|
||||
r = -EINVAL;
|
||||
goto on_failure;
|
||||
}
|
||||
|
||||
if (l > 0) { /* Trailing rubbish? */
|
||||
r = -ENAMETOOLONG;
|
||||
goto on_failure;
|
||||
}
|
||||
|
||||
*(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
|
||||
break;
|
||||
}
|
||||
|
||||
if (d == -ERANGE) {
|
||||
/* c == 00ZZZZ00 */
|
||||
if (c & 3) {
|
||||
r = -EINVAL;
|
||||
goto on_failure;
|
||||
}
|
||||
|
||||
if (l > 0) { /* Trailing rubbish? */
|
||||
r = -ENAMETOOLONG;
|
||||
goto on_failure;
|
||||
}
|
||||
|
||||
*(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
|
||||
*(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
|
||||
break;
|
||||
}
|
||||
|
||||
*(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
|
||||
*(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
|
||||
*(z++) = (uint8_t) c << 6 | (uint8_t) d; /* ZZWWWWWW */
|
||||
}
|
||||
|
||||
*z = '\0';
|
||||
|
||||
NM_SET_OUT(ret_size, (gsize) (z - buf));
|
||||
NM_SET_OUT(ret, g_steal_pointer(&buf));
|
||||
return 0;
|
||||
|
||||
on_failure:
|
||||
if (secure)
|
||||
nm_explicit_bzero(buf, len);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const char *
|
||||
skip_slash_or_dot(const char *p)
|
||||
{
|
||||
for (; !nm_str_is_empty(p);) {
|
||||
if (p[0] == '/') {
|
||||
p += 1;
|
||||
continue;
|
||||
}
|
||||
if (p[0] == '.' && p[1] == '/') {
|
||||
p += 2;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
int
|
||||
nm_path_find_first_component(const char **p, gboolean accept_dot_dot, const char **ret)
|
||||
{
|
||||
const char *q, *first, *end_first, *next;
|
||||
size_t len;
|
||||
|
||||
/* Copied from systemd's path_compare()
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/basic/path-util.c#L809 */
|
||||
|
||||
nm_assert(p);
|
||||
|
||||
/* When a path is input, then returns the pointer to the first component and its length, and
|
||||
* move the input pointer to the next component or nul. This skips both over any '/'
|
||||
* immediately *before* and *after* the first component before returning.
|
||||
*
|
||||
* Examples
|
||||
* Input: p: "//.//aaa///bbbbb/cc"
|
||||
* Output: p: "bbbbb///cc"
|
||||
* ret: "aaa///bbbbb/cc"
|
||||
* return value: 3 (== strlen("aaa"))
|
||||
*
|
||||
* Input: p: "aaa//"
|
||||
* Output: p: (pointer to NUL)
|
||||
* ret: "aaa//"
|
||||
* return value: 3 (== strlen("aaa"))
|
||||
*
|
||||
* Input: p: "/", ".", ""
|
||||
* Output: p: (pointer to NUL)
|
||||
* ret: NULL
|
||||
* return value: 0
|
||||
*
|
||||
* Input: p: NULL
|
||||
* Output: p: NULL
|
||||
* ret: NULL
|
||||
* return value: 0
|
||||
*
|
||||
* Input: p: "(too long component)"
|
||||
* Output: return value: -EINVAL
|
||||
*
|
||||
* (when accept_dot_dot is false)
|
||||
* Input: p: "//..//aaa///bbbbb/cc"
|
||||
* Output: return value: -EINVAL
|
||||
*/
|
||||
|
||||
q = *p;
|
||||
|
||||
first = skip_slash_or_dot(q);
|
||||
if (nm_str_is_empty(first)) {
|
||||
*p = first;
|
||||
if (ret)
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (nm_streq(first, ".")) {
|
||||
*p = first + 1;
|
||||
if (ret)
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
end_first = strchrnul(first, '/');
|
||||
len = end_first - first;
|
||||
|
||||
if (len > NAME_MAX)
|
||||
return -EINVAL;
|
||||
if (!accept_dot_dot && len == 2 && first[0] == '.' && first[1] == '.')
|
||||
return -EINVAL;
|
||||
|
||||
next = skip_slash_or_dot(end_first);
|
||||
|
||||
*p = next + (nm_streq(next, ".") ? 1 : 0);
|
||||
if (ret)
|
||||
*ret = first;
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
nm_path_compare(const char *a, const char *b)
|
||||
{
|
||||
/* Copied from systemd's path_compare()
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/basic/path-util.c#L415 */
|
||||
|
||||
/* Order NULL before non-NULL */
|
||||
NM_CMP_SELF(a, b);
|
||||
|
||||
/* A relative path and an absolute path must not compare as equal.
|
||||
* Which one is sorted before the other does not really matter.
|
||||
* Here a relative path is ordered before an absolute path. */
|
||||
NM_CMP_DIRECT(nm_path_is_absolute(a), nm_path_is_absolute(b));
|
||||
|
||||
for (;;) {
|
||||
const char *aa, *bb;
|
||||
int j, k;
|
||||
|
||||
j = nm_path_find_first_component(&a, TRUE, &aa);
|
||||
k = nm_path_find_first_component(&b, TRUE, &bb);
|
||||
|
||||
if (j < 0 || k < 0) {
|
||||
/* When one of paths is invalid, order invalid path after valid one. */
|
||||
NM_CMP_DIRECT(j < 0, k < 0);
|
||||
|
||||
/* fallback to use strcmp() if both paths are invalid. */
|
||||
NM_CMP_DIRECT_STRCMP(a, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Order prefixes first: "/foo" before "/foo/bar" */
|
||||
if (j == 0) {
|
||||
if (k == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
if (k == 0)
|
||||
return 1;
|
||||
|
||||
/* Alphabetical sort: "/foo/aaa" before "/foo/b" */
|
||||
NM_CMP_DIRECT_MEMCMP(aa, bb, NM_MIN(j, k));
|
||||
|
||||
/* Sort "/foo/a" before "/foo/aaa" */
|
||||
NM_CMP_DIRECT(j, k);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
nm_path_startswith_full(const char *path, const char *prefix, gboolean accept_dot_dot)
|
||||
{
|
||||
/* Copied from systemd's path_startswith_full()
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/basic/path-util.c#L375 */
|
||||
|
||||
nm_assert(path);
|
||||
nm_assert(prefix);
|
||||
|
||||
/* Returns a pointer to the start of the first component after the parts matched by
|
||||
* the prefix, iff
|
||||
* - both paths are absolute or both paths are relative,
|
||||
* and
|
||||
* - each component in prefix in turn matches a component in path at the same position.
|
||||
* An empty string will be returned when the prefix and path are equivalent.
|
||||
*
|
||||
* Returns NULL otherwise.
|
||||
*/
|
||||
|
||||
if ((path[0] == '/') != (prefix[0] == '/'))
|
||||
return NULL;
|
||||
|
||||
for (;;) {
|
||||
const char *p, *q;
|
||||
int r, k;
|
||||
|
||||
r = nm_path_find_first_component(&path, accept_dot_dot, &p);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
|
||||
k = nm_path_find_first_component(&prefix, accept_dot_dot, &q);
|
||||
if (k < 0)
|
||||
return NULL;
|
||||
|
||||
if (k == 0)
|
||||
return (char *) (p ?: path);
|
||||
|
||||
if (r != k)
|
||||
return NULL;
|
||||
|
||||
if (strncmp(p, q, r) != 0)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
nm_path_simplify(char *path)
|
||||
{
|
||||
bool add_slash = false;
|
||||
char *f = path;
|
||||
int r;
|
||||
|
||||
/* Copied from systemd's path_simplify()
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/basic/path-util.c#L325 */
|
||||
|
||||
nm_assert(path);
|
||||
|
||||
/* Removes redundant inner and trailing slashes. Also removes unnecessary dots.
|
||||
* Modifies the passed string in-place.
|
||||
*
|
||||
* ///foo//./bar/. becomes /foo/bar
|
||||
* .//./foo//./bar/. becomes foo/bar
|
||||
*/
|
||||
|
||||
if (path[0] == '\0')
|
||||
return path;
|
||||
|
||||
if (nm_path_is_absolute(path))
|
||||
f++;
|
||||
|
||||
for (const char *p = f;;) {
|
||||
const char *e;
|
||||
|
||||
r = nm_path_find_first_component(&p, TRUE, &e);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (add_slash)
|
||||
*f++ = '/';
|
||||
|
||||
if (r < 0) {
|
||||
/* if path is invalid, then refuse to simplify remaining part. */
|
||||
memmove(f, p, strlen(p) + 1);
|
||||
return path;
|
||||
}
|
||||
|
||||
memmove(f, e, r);
|
||||
f += r;
|
||||
|
||||
add_slash = TRUE;
|
||||
}
|
||||
|
||||
/* Special rule, if we stripped everything, we need a "." for the current directory. */
|
||||
if (f == path)
|
||||
*f++ = '.';
|
||||
|
||||
*f = '\0';
|
||||
return path;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
valid_ldh_char(char c)
|
||||
{
|
||||
/* "LDH" → "Letters, digits, hyphens", as per RFC 5890, Section 2.3.1 */
|
||||
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_hostname_is_valid:
|
||||
* @s: the hostname to check.
|
||||
* @trailing_dot: Accept trailing dot on multi-label names.
|
||||
*
|
||||
* Return: %TRUE if valid.
|
||||
*/
|
||||
gboolean
|
||||
nm_hostname_is_valid(const char *s, gboolean trailing_dot)
|
||||
{
|
||||
unsigned n_dots = 0;
|
||||
const char *p;
|
||||
gboolean dot;
|
||||
gboolean hyphen;
|
||||
|
||||
/* Copied from systemd's hostname_is_valid()
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/basic/hostname-util.c#L85 */
|
||||
|
||||
/* Check if s looks like a valid hostname or FQDN. This does not do full DNS validation, but only
|
||||
* checks if the name is composed of allowed characters and the length is not above the maximum
|
||||
* allowed by Linux (c.f. dns_name_is_valid()). A trailing dot is allowed if
|
||||
* VALID_HOSTNAME_TRAILING_DOT flag is set and at least two components are present in the name. Note
|
||||
* that due to the restricted charset and length this call is substantially more conservative than
|
||||
* dns_name_is_valid(). Doesn't accept empty hostnames, hostnames with leading dots, and hostnames
|
||||
* with multiple dots in a sequence. Doesn't allow hyphens at the beginning or end of label. */
|
||||
|
||||
if (nm_str_is_empty(s))
|
||||
return FALSE;
|
||||
|
||||
for (p = s, dot = hyphen = TRUE; *p; p++)
|
||||
if (*p == '.') {
|
||||
if (dot || hyphen)
|
||||
return FALSE;
|
||||
|
||||
dot = TRUE;
|
||||
hyphen = FALSE;
|
||||
n_dots++;
|
||||
|
||||
} else if (*p == '-') {
|
||||
if (dot)
|
||||
return FALSE;
|
||||
|
||||
dot = FALSE;
|
||||
hyphen = TRUE;
|
||||
|
||||
} else {
|
||||
if (!valid_ldh_char(*p))
|
||||
return FALSE;
|
||||
|
||||
dot = FALSE;
|
||||
hyphen = FALSE;
|
||||
}
|
||||
|
||||
if (dot && (n_dots < 2 || !trailing_dot))
|
||||
return FALSE;
|
||||
if (hyphen)
|
||||
return FALSE;
|
||||
|
||||
/* Note that HOST_NAME_MAX is 64 on Linux, but DNS allows domain names up to
|
||||
* 255 characters */
|
||||
if (p - s > HOST_NAME_MAX)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3308,4 +3308,46 @@ gboolean nm_utils_validate_hostname(const char *hostname);
|
|||
|
||||
void nm_utils_thread_local_register_destroy(gpointer tls_data, GDestroyNotify destroy_notify);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int nm_unbase64char(char c);
|
||||
int nm_unbase64mem_full(const char *p, gsize l, gboolean secure, guint8 **ret, gsize *ret_size);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline gboolean
|
||||
nm_path_is_absolute(const char *p)
|
||||
{
|
||||
/* Copied from systemd's path_is_absolute()
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/basic/path-util.h#L50 */
|
||||
|
||||
nm_assert(p);
|
||||
return p[0] == '/';
|
||||
}
|
||||
|
||||
int nm_path_find_first_component(const char **p, gboolean accept_dot_dot, const char **ret);
|
||||
|
||||
int nm_path_compare(const char *a, const char *b);
|
||||
|
||||
static inline gboolean
|
||||
nm_path_equal(const char *a, const char *b)
|
||||
{
|
||||
return nm_path_compare(a, b) == 0;
|
||||
}
|
||||
|
||||
char *nm_path_simplify(char *path);
|
||||
|
||||
char *
|
||||
nm_path_startswith_full(const char *path, const char *prefix, gboolean accept_dot_dot) _nm_pure;
|
||||
|
||||
static inline char *
|
||||
nm_path_startswith(const char *path, const char *prefix)
|
||||
{
|
||||
return nm_path_startswith_full(path, prefix, TRUE);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean nm_hostname_is_valid(const char *s, gboolean trailing_dot);
|
||||
|
||||
#endif /* __NM_SHARED_UTILS_H__ */
|
||||
|
|
|
|||
|
|
@ -1556,6 +1556,600 @@ test_parse_env_file(void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_unbase64char(void)
|
||||
{
|
||||
static const int expected[128] = {
|
||||
[0] = -1, [1] = -1, [2] = -1, [3] = -1, [4] = -1, [5] = -1, [6] = -1,
|
||||
[7] = -1, [8] = -1, [9] = -1, [10] = -1, [11] = -1, [12] = -1, [13] = -1,
|
||||
[14] = -1, [15] = -1, [16] = -1, [17] = -1, [18] = -1, [19] = -1, [20] = -1,
|
||||
[21] = -1, [22] = -1, [23] = -1, [24] = -1, [25] = -1, [26] = -1, [27] = -1,
|
||||
[28] = -1, [29] = -1, [30] = -1, [31] = -1, [32] = -1, [33] = -1, [34] = -1,
|
||||
[35] = -1, [36] = -1, [37] = -1, [38] = -1, [39] = -1, [40] = -1, [41] = -1,
|
||||
[42] = -1, ['+'] = 62, [44] = -1, [45] = -1, [46] = -1, ['/'] = 63, ['0'] = 52,
|
||||
['1'] = 53, ['2'] = 54, ['3'] = 55, ['4'] = 56, ['5'] = 57, ['6'] = 58, ['7'] = 59,
|
||||
['8'] = 60, ['9'] = 61, [58] = -1, [59] = -1, [60] = -1, [61] = -1, [62] = -1,
|
||||
[63] = -1, [64] = -1, ['A'] = 0, ['B'] = 1, ['C'] = 2, ['D'] = 3, ['E'] = 4,
|
||||
['F'] = 5, ['G'] = 6, ['H'] = 7, ['I'] = 8, ['J'] = 9, ['K'] = 10, ['L'] = 11,
|
||||
['M'] = 12, ['N'] = 13, ['O'] = 14, ['P'] = 15, ['Q'] = 16, ['R'] = 17, ['S'] = 18,
|
||||
['T'] = 19, ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23, ['Y'] = 24, ['Z'] = 25,
|
||||
[91] = -1, [92] = -1, [93] = -1, [94] = -1, [95] = -1, [96] = -1, ['a'] = 26,
|
||||
['b'] = 27, ['c'] = 28, ['d'] = 29, ['e'] = 30, ['f'] = 31, ['g'] = 32, ['h'] = 33,
|
||||
['i'] = 34, ['j'] = 35, ['k'] = 36, ['l'] = 37, ['m'] = 38, ['n'] = 39, ['o'] = 40,
|
||||
['p'] = 41, ['q'] = 42, ['r'] = 43, ['s'] = 44, ['t'] = 45, ['u'] = 46, ['v'] = 47,
|
||||
['w'] = 48, ['x'] = 49, ['y'] = 50, ['z'] = 51, [123] = -1, [124] = -1, [125] = -1,
|
||||
[126] = -1, [127] = -1,
|
||||
};
|
||||
int i;
|
||||
|
||||
/* Copied from systemd's TEST(unbase64char)
|
||||
* https://github.com/systemd/systemd/blob/688efe7703328c5a0251fafac55757b8864a9f9a/src/test/test-hexdecoct.c#L44 */
|
||||
|
||||
g_assert_cmpint(nm_unbase64char('A'), ==, 0);
|
||||
g_assert_cmpint(nm_unbase64char('Z'), ==, 25);
|
||||
g_assert_cmpint(nm_unbase64char('a'), ==, 26);
|
||||
g_assert_cmpint(nm_unbase64char('z'), ==, 51);
|
||||
g_assert_cmpint(nm_unbase64char('0'), ==, 52);
|
||||
g_assert_cmpint(nm_unbase64char('9'), ==, 61);
|
||||
g_assert_cmpint(nm_unbase64char('+'), ==, 62);
|
||||
g_assert_cmpint(nm_unbase64char('/'), ==, 63);
|
||||
g_assert_cmpint(nm_unbase64char('='), ==, -ERANGE);
|
||||
g_assert_cmpint(nm_unbase64char('\0'), ==, -EINVAL);
|
||||
g_assert_cmpint(nm_unbase64char('\1'), ==, -EINVAL);
|
||||
g_assert_cmpint(nm_unbase64char('\x7F'), ==, -EINVAL);
|
||||
g_assert_cmpint(nm_unbase64char('\x80'), ==, -EINVAL);
|
||||
g_assert_cmpint(nm_unbase64char('\xFF'), ==, -EINVAL);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
int base64;
|
||||
|
||||
base64 = nm_unbase64char((char) i);
|
||||
|
||||
if (base64 < 0) {
|
||||
if (((char) i) == '=')
|
||||
g_assert_cmpint(base64, ==, -ERANGE);
|
||||
else
|
||||
g_assert_cmpint(base64, ==, -EINVAL);
|
||||
base64 = -1;
|
||||
}
|
||||
|
||||
if (i >= G_N_ELEMENTS(expected)) {
|
||||
g_assert_cmpint(base64, ==, -1);
|
||||
continue;
|
||||
}
|
||||
g_assert_cmpint(base64, ==, expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_unbase64mem1(void)
|
||||
{
|
||||
nm_auto_str_buf NMStrBuf encoded_wrapped = NM_STR_BUF_INIT(400, FALSE);
|
||||
uint8_t data[4096];
|
||||
int i_run;
|
||||
|
||||
/* Copied from systemd's TEST(base64mem_linebreak)
|
||||
* https://github.com/systemd/systemd/blob/688efe7703328c5a0251fafac55757b8864a9f9a/src/test/test-hexdecoct.c#L280 */
|
||||
|
||||
for (i_run = 0; i_run < 20; i_run++) {
|
||||
gs_free char *encoded = NULL;
|
||||
gs_free guint8 *decoded = NULL;
|
||||
gsize decoded_size;
|
||||
guint64 n;
|
||||
guint64 m;
|
||||
guint64 i;
|
||||
guint64 j;
|
||||
gssize l;
|
||||
int r;
|
||||
|
||||
/* Try a bunch of differently sized blobs */
|
||||
n = nmtst_get_rand_uint64() % sizeof(data);
|
||||
nmtst_rand_buf(NULL, data, n);
|
||||
|
||||
/* Break at various different columns */
|
||||
m = 1 + (nmtst_get_rand_uint64() % (n + 5));
|
||||
|
||||
encoded = g_base64_encode(data, n);
|
||||
g_assert(encoded);
|
||||
l = strlen(encoded);
|
||||
|
||||
nm_str_buf_reset(&encoded_wrapped);
|
||||
for (i = 0, j = 0; i < l; i++, j++) {
|
||||
if (j == m) {
|
||||
nm_str_buf_append_c(&encoded_wrapped, '\n');
|
||||
j = 0;
|
||||
}
|
||||
nm_str_buf_append_c(&encoded_wrapped, encoded[i]);
|
||||
}
|
||||
|
||||
g_assert_cmpint(strlen(nm_str_buf_get_str(&encoded_wrapped)), ==, encoded_wrapped.len);
|
||||
|
||||
r = nm_unbase64mem_full(nm_str_buf_get_str(&encoded_wrapped),
|
||||
nmtst_get_rand_bool() ? SIZE_MAX : encoded_wrapped.len,
|
||||
nmtst_get_rand_bool(),
|
||||
&decoded,
|
||||
&decoded_size);
|
||||
g_assert_cmpint(r, >=, 0);
|
||||
g_assert_cmpmem(data, n, decoded, decoded_size);
|
||||
|
||||
for (j = 0; j < encoded_wrapped.len; j++)
|
||||
g_assert((nm_str_buf_get_str(&encoded_wrapped)[j] == '\n') == (j % (m + 1) == m));
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_assert_unbase64mem(const char *input, const char *output, int ret)
|
||||
{
|
||||
gs_free guint8 *buffer = NULL;
|
||||
gsize size = 0;
|
||||
int r;
|
||||
|
||||
r = nm_unbase64mem_full(input, SIZE_MAX, nmtst_get_rand_bool(), &buffer, &size);
|
||||
g_assert_cmpint(r, ==, ret);
|
||||
|
||||
if (ret >= 0) {
|
||||
g_assert_cmpmem(buffer, size, output, strlen(output));
|
||||
g_assert_cmpint(((const char *) buffer)[size], ==, '\0');
|
||||
} else {
|
||||
g_assert(!buffer);
|
||||
g_assert_cmpint(size, ==, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_unbase64mem2(void)
|
||||
{
|
||||
/* Copied from systemd's TEST(unbase64mem)
|
||||
* https://github.com/systemd/systemd/blob/688efe7703328c5a0251fafac55757b8864a9f9a/src/test/test-hexdecoct.c#L324 */
|
||||
|
||||
_assert_unbase64mem("", "", 0);
|
||||
_assert_unbase64mem("Zg==", "f", 0);
|
||||
_assert_unbase64mem("Zm8=", "fo", 0);
|
||||
_assert_unbase64mem("Zm9v", "foo", 0);
|
||||
_assert_unbase64mem("Zm9vYg==", "foob", 0);
|
||||
_assert_unbase64mem("Zm9vYmE=", "fooba", 0);
|
||||
_assert_unbase64mem("Zm9vYmFy", "foobar", 0);
|
||||
|
||||
_assert_unbase64mem(" ", "", 0);
|
||||
_assert_unbase64mem(" \n\r ", "", 0);
|
||||
_assert_unbase64mem(" Zg\n== ", "f", 0);
|
||||
_assert_unbase64mem(" Zm 8=\r", "fo", 0);
|
||||
_assert_unbase64mem(" Zm9\n\r\r\nv ", "foo", 0);
|
||||
_assert_unbase64mem(" Z m9vYg==\n\r", "foob", 0);
|
||||
_assert_unbase64mem(" Zm 9vYmE= ", "fooba", 0);
|
||||
_assert_unbase64mem(" Z m9v YmFy ", "foobar", 0);
|
||||
|
||||
_assert_unbase64mem("A", NULL, -EPIPE);
|
||||
_assert_unbase64mem("A====", NULL, -EINVAL);
|
||||
_assert_unbase64mem("AAB==", NULL, -EINVAL);
|
||||
_assert_unbase64mem(" A A A B = ", NULL, -EINVAL);
|
||||
_assert_unbase64mem(" Z m 8 = q u u x ", NULL, -ENAMETOOLONG);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_test_unbase64mem_mem(const char *base64, const guint8 *expected_arr, gsize expected_len)
|
||||
{
|
||||
gs_free char *expected_base64 = NULL;
|
||||
int r;
|
||||
nm_auto_free guint8 *exp2_arr = NULL;
|
||||
nm_auto_free guint8 *exp3_arr = NULL;
|
||||
gsize exp2_len;
|
||||
gsize exp3_len;
|
||||
|
||||
expected_base64 = g_base64_encode(expected_arr, expected_len);
|
||||
|
||||
r = nm_unbase64mem_full(expected_base64, strlen(expected_base64), TRUE, &exp2_arr, &exp2_len);
|
||||
g_assert_cmpint(r, ==, 0);
|
||||
g_assert_cmpmem(expected_arr, expected_len, exp2_arr, exp2_len);
|
||||
|
||||
if (!nm_streq(base64, expected_base64)) {
|
||||
r = nm_unbase64mem_full(base64, strlen(base64), TRUE, &exp3_arr, &exp3_len);
|
||||
g_assert_cmpint(r, ==, 0);
|
||||
g_assert_cmpmem(expected_arr, expected_len, exp3_arr, exp3_len);
|
||||
}
|
||||
}
|
||||
|
||||
#define _test_unbase64mem(base64, expected_str) \
|
||||
_test_unbase64mem_mem(base64, (const guint8 *) "" expected_str "", NM_STRLEN(expected_str))
|
||||
|
||||
static void
|
||||
_test_unbase64mem_inval(const char *base64)
|
||||
{
|
||||
gs_free guint8 *exp_arr = NULL;
|
||||
gsize exp_len = 0;
|
||||
int r;
|
||||
|
||||
r = nm_unbase64mem_full(base64, strlen(base64), TRUE, &exp_arr, &exp_len);
|
||||
g_assert_cmpint(r, <, 0);
|
||||
g_assert(!exp_arr);
|
||||
g_assert(exp_len == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_unbase64mem3(void)
|
||||
{
|
||||
gs_free char *rnd_base64 = NULL;
|
||||
guint8 rnd_buf[30];
|
||||
guint i, rnd_len;
|
||||
|
||||
_test_unbase64mem("", "");
|
||||
_test_unbase64mem(" ", "");
|
||||
_test_unbase64mem(" Y Q == ", "a");
|
||||
_test_unbase64mem(" Y WJjZGV mZ 2g = ", "abcdefgh");
|
||||
_test_unbase64mem_inval(" Y %WJjZGV mZ 2g = ");
|
||||
_test_unbase64mem_inval(" Y %WJjZGV mZ 2g = a");
|
||||
_test_unbase64mem("YQ==", "a");
|
||||
_test_unbase64mem_inval("YQ==a");
|
||||
|
||||
rnd_len = nmtst_get_rand_uint32() % sizeof(rnd_buf);
|
||||
for (i = 0; i < rnd_len; i++)
|
||||
rnd_buf[i] = nmtst_get_rand_uint32() % 256;
|
||||
rnd_base64 = g_base64_encode(rnd_buf, rnd_len);
|
||||
_test_unbase64mem_mem(rnd_base64, rnd_buf, rnd_len);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
assert_path_compare(const char *a, const char *b, int expected)
|
||||
{
|
||||
int r;
|
||||
|
||||
g_assert(NM_IN_SET(expected, -1, 0, 1));
|
||||
|
||||
g_assert_cmpint(nm_path_compare(a, a), ==, 0);
|
||||
g_assert_cmpint(nm_path_compare(b, b), ==, 0);
|
||||
|
||||
r = nm_path_compare(a, b);
|
||||
g_assert_cmpint(r, ==, expected);
|
||||
r = nm_path_compare(b, a);
|
||||
g_assert_cmpint(r, ==, -expected);
|
||||
|
||||
g_assert(nm_path_equal(a, a) == 1);
|
||||
g_assert(nm_path_equal(b, b) == 1);
|
||||
g_assert(nm_path_equal(a, b) == (expected == 0));
|
||||
g_assert(nm_path_equal(b, a) == (expected == 0));
|
||||
}
|
||||
|
||||
static void
|
||||
test_path_compare(void)
|
||||
{
|
||||
/* Copied from systemd.
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/test/test-path-util.c#L126 */
|
||||
|
||||
assert_path_compare("/goo", "/goo", 0);
|
||||
assert_path_compare("/goo", "/goo", 0);
|
||||
assert_path_compare("//goo", "/goo", 0);
|
||||
assert_path_compare("//goo/////", "/goo", 0);
|
||||
assert_path_compare("goo/////", "goo", 0);
|
||||
assert_path_compare("/goo/boo", "/goo//boo", 0);
|
||||
assert_path_compare("//goo/boo", "/goo/boo//", 0);
|
||||
assert_path_compare("//goo/././//./boo//././//", "/goo/boo//.", 0);
|
||||
assert_path_compare("/.", "//.///", 0);
|
||||
assert_path_compare("/x", "x/", 1);
|
||||
assert_path_compare("x/", "/", -1);
|
||||
assert_path_compare("/x/./y", "x/y", 1);
|
||||
assert_path_compare("/x/./y", "/x/y", 0);
|
||||
assert_path_compare("/x/./././y", "/x/y/././.", 0);
|
||||
assert_path_compare("./x/./././y", "./x/y/././.", 0);
|
||||
assert_path_compare(".", "./.", 0);
|
||||
assert_path_compare(".", "././.", 0);
|
||||
assert_path_compare("./..", ".", 1);
|
||||
assert_path_compare("x/.y", "x/y", -1);
|
||||
assert_path_compare("foo", "/foo", -1);
|
||||
assert_path_compare("/foo", "/foo/bar", -1);
|
||||
assert_path_compare("/foo/aaa", "/foo/b", -1);
|
||||
assert_path_compare("/foo/aaa", "/foo/b/a", -1);
|
||||
assert_path_compare("/foo/a", "/foo/aaa", -1);
|
||||
assert_path_compare("/foo/a/b", "/foo/aaa", -1);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_path_equal(void)
|
||||
{
|
||||
#define _path_equal_check(path, expected) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
const char *_path0 = (path); \
|
||||
const char *_expected = (expected); \
|
||||
gs_free char *_path = g_strdup(_path0); \
|
||||
const char *_path_result; \
|
||||
\
|
||||
_path_result = nm_path_simplify(_path); \
|
||||
g_assert(_path_result == _path); \
|
||||
g_assert_cmpstr(_path, ==, _expected); \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
_path_equal_check("", "");
|
||||
_path_equal_check(".", ".");
|
||||
_path_equal_check("..", "..");
|
||||
_path_equal_check("/..", "/..");
|
||||
_path_equal_check("//..", "/..");
|
||||
_path_equal_check("/.", "/");
|
||||
_path_equal_check("./", ".");
|
||||
_path_equal_check("./.", ".");
|
||||
_path_equal_check(".///.", ".");
|
||||
_path_equal_check(".///./", ".");
|
||||
_path_equal_check(".////", ".");
|
||||
_path_equal_check("//..//foo/", "/../foo");
|
||||
_path_equal_check("///foo//./bar/.", "/foo/bar");
|
||||
_path_equal_check(".//./foo//./bar/.", "foo/bar");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
assert_path_find_first_component(const char *path,
|
||||
gboolean accept_dot_dot,
|
||||
const char *const *expected,
|
||||
int ret)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = path;;) {
|
||||
const char *e;
|
||||
int r;
|
||||
|
||||
r = nm_path_find_first_component(&p, accept_dot_dot, &e);
|
||||
if (r <= 0) {
|
||||
if (r == 0) {
|
||||
if (path)
|
||||
g_assert(p == path + strlen(path));
|
||||
else
|
||||
g_assert(!p);
|
||||
g_assert(!e);
|
||||
}
|
||||
g_assert(r == ret);
|
||||
g_assert(!expected || !*expected);
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert(e);
|
||||
g_assert(strcspn(e, "/") == (size_t) r);
|
||||
g_assert(strlen(*expected) == (size_t) r);
|
||||
g_assert(strncmp(e, *expected++, r) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_path_find_first_component(void)
|
||||
{
|
||||
gs_free char *hoge = NULL;
|
||||
char foo[NAME_MAX * 2];
|
||||
|
||||
/* Copied from systemd.
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/test/test-path-util.c#L631 */
|
||||
|
||||
assert_path_find_first_component(NULL, false, NULL, 0);
|
||||
assert_path_find_first_component("", false, NULL, 0);
|
||||
assert_path_find_first_component("/", false, NULL, 0);
|
||||
assert_path_find_first_component(".", false, NULL, 0);
|
||||
assert_path_find_first_component("./", false, NULL, 0);
|
||||
assert_path_find_first_component("./.", false, NULL, 0);
|
||||
assert_path_find_first_component("..", false, NULL, -EINVAL);
|
||||
assert_path_find_first_component("/..", false, NULL, -EINVAL);
|
||||
assert_path_find_first_component("./..", false, NULL, -EINVAL);
|
||||
assert_path_find_first_component("////./././//.", false, NULL, 0);
|
||||
assert_path_find_first_component("a/b/c", false, NM_MAKE_STRV("a", "b", "c"), 0);
|
||||
assert_path_find_first_component("././//.///aa/bbb//./ccc",
|
||||
false,
|
||||
NM_MAKE_STRV("aa", "bbb", "ccc"),
|
||||
0);
|
||||
assert_path_find_first_component("././//.///aa/.../../bbb//./ccc/.",
|
||||
false,
|
||||
NM_MAKE_STRV("aa", "..."),
|
||||
-EINVAL);
|
||||
assert_path_find_first_component("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.",
|
||||
false,
|
||||
NM_MAKE_STRV("aaa", ".bbb"),
|
||||
-EINVAL);
|
||||
assert_path_find_first_component("a/foo./b", false, NM_MAKE_STRV("a", "foo.", "b"), 0);
|
||||
|
||||
assert_path_find_first_component(NULL, true, NULL, 0);
|
||||
assert_path_find_first_component("", true, NULL, 0);
|
||||
assert_path_find_first_component("/", true, NULL, 0);
|
||||
assert_path_find_first_component(".", true, NULL, 0);
|
||||
assert_path_find_first_component("./", true, NULL, 0);
|
||||
assert_path_find_first_component("./.", true, NULL, 0);
|
||||
assert_path_find_first_component("..", true, NM_MAKE_STRV(".."), 0);
|
||||
assert_path_find_first_component("/..", true, NM_MAKE_STRV(".."), 0);
|
||||
assert_path_find_first_component("./..", true, NM_MAKE_STRV(".."), 0);
|
||||
assert_path_find_first_component("////./././//.", true, NULL, 0);
|
||||
assert_path_find_first_component("a/b/c", true, NM_MAKE_STRV("a", "b", "c"), 0);
|
||||
assert_path_find_first_component("././//.///aa/bbb//./ccc",
|
||||
true,
|
||||
NM_MAKE_STRV("aa", "bbb", "ccc"),
|
||||
0);
|
||||
assert_path_find_first_component("././//.///aa/.../../bbb//./ccc/.",
|
||||
true,
|
||||
NM_MAKE_STRV("aa", "...", "..", "bbb", "ccc"),
|
||||
0);
|
||||
assert_path_find_first_component("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.",
|
||||
true,
|
||||
NM_MAKE_STRV("aaa", ".bbb", "..", "c.", "d.dd", "..eeee"),
|
||||
0);
|
||||
assert_path_find_first_component("a/foo./b", true, NM_MAKE_STRV("a", "foo.", "b"), 0);
|
||||
|
||||
memset(foo, 'a', sizeof(foo) - 1);
|
||||
foo[sizeof(foo) - 1] = '\0';
|
||||
|
||||
assert_path_find_first_component(foo, false, NULL, -EINVAL);
|
||||
assert_path_find_first_component(foo, true, NULL, -EINVAL);
|
||||
|
||||
hoge = g_strjoin("", "a/b/c/", foo, "//d/e/.//f/", NULL);
|
||||
g_assert(hoge);
|
||||
|
||||
assert_path_find_first_component(hoge, false, NM_MAKE_STRV("a", "b", "c"), -EINVAL);
|
||||
assert_path_find_first_component(hoge, true, NM_MAKE_STRV("a", "b", "c"), -EINVAL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
assert_path_startswith(const char *path,
|
||||
const char *prefix,
|
||||
const char *skipped,
|
||||
const char *expected)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
p = nm_path_startswith(path, prefix);
|
||||
g_assert_cmpstr(p, ==, expected);
|
||||
if (p) {
|
||||
gs_free char *q = NULL;
|
||||
|
||||
g_assert(skipped);
|
||||
q = g_strjoin("", skipped, p, NULL);
|
||||
g_assert_cmpstr(q, ==, path);
|
||||
g_assert(p == path + strlen(skipped));
|
||||
} else
|
||||
g_assert(!skipped);
|
||||
}
|
||||
|
||||
static void
|
||||
test_path_startswith(void)
|
||||
{
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo", "/foo/", "bar/barfoo/");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/", "/foo/", "bar/barfoo/");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/", "/", "foo/bar/barfoo/");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "////", "/", "foo/bar/barfoo/");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///", "/foo/bar/barfoo/", "");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////", "/foo/bar/barfoo/", "");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/", "/foo/bar/barfoo/", "");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/", "/foo/bar/barfoo/", "");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/", "/foo/bar/barfoo/", "");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo", "/foo/bar/barfoo/", "");
|
||||
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/bar/foo", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/f/b/b/", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/barfo", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/bar", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/fo", NULL, NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
assert_path_simplify(const char *in, const char *out)
|
||||
{
|
||||
gs_free char *p = NULL;
|
||||
|
||||
g_assert(in);
|
||||
p = g_strdup(in);
|
||||
nm_path_simplify(p);
|
||||
g_assert_cmpstr(p, ==, out);
|
||||
}
|
||||
|
||||
static void
|
||||
test_path_simplify(void)
|
||||
{
|
||||
gs_free char *hoge = NULL;
|
||||
gs_free char *hoge_out = NULL;
|
||||
char foo[NAME_MAX * 2];
|
||||
|
||||
assert_path_simplify("", "");
|
||||
assert_path_simplify("aaa/bbb////ccc", "aaa/bbb/ccc");
|
||||
assert_path_simplify("//aaa/.////ccc", "/aaa/ccc");
|
||||
assert_path_simplify("///", "/");
|
||||
assert_path_simplify("///.//", "/");
|
||||
assert_path_simplify("///.//.///", "/");
|
||||
assert_path_simplify("////.././///../.", "/../..");
|
||||
assert_path_simplify(".", ".");
|
||||
assert_path_simplify("./", ".");
|
||||
assert_path_simplify(".///.//./.", ".");
|
||||
assert_path_simplify(".///.//././/", ".");
|
||||
assert_path_simplify("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.",
|
||||
"/aaa/.bbb/../c./d.dd/..eeee");
|
||||
assert_path_simplify("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
|
||||
"/aaa/.bbb/../c./d.dd/..eeee/..");
|
||||
assert_path_simplify(".//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
|
||||
"aaa/.bbb/../c./d.dd/..eeee/..");
|
||||
assert_path_simplify("..//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
|
||||
"../aaa/.bbb/../c./d.dd/..eeee/..");
|
||||
|
||||
memset(foo, 'a', sizeof(foo) - 1);
|
||||
foo[sizeof(foo) - 1] = '\0';
|
||||
|
||||
assert_path_simplify(foo, foo);
|
||||
|
||||
hoge = g_strjoin("", "/", foo, NULL);
|
||||
g_assert(hoge);
|
||||
assert_path_simplify(hoge, hoge);
|
||||
nm_clear_g_free(&hoge);
|
||||
|
||||
hoge =
|
||||
g_strjoin("", "a////.//././//./b///././/./c/////././//./", foo, "//.//////d/e/.//f/", NULL);
|
||||
g_assert(hoge);
|
||||
|
||||
hoge_out = g_strjoin("", "a/b/c/", foo, "//.//////d/e/.//f/", NULL);
|
||||
g_assert(hoge_out);
|
||||
|
||||
assert_path_simplify(hoge, hoge_out);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_hostname_is_valid(void)
|
||||
{
|
||||
g_assert(nm_hostname_is_valid("foobar", FALSE));
|
||||
g_assert(nm_hostname_is_valid("foobar.com", FALSE));
|
||||
g_assert(!nm_hostname_is_valid("foobar.com.", FALSE));
|
||||
g_assert(nm_hostname_is_valid("fooBAR", FALSE));
|
||||
g_assert(nm_hostname_is_valid("fooBAR.com", FALSE));
|
||||
g_assert(!nm_hostname_is_valid("fooBAR.", FALSE));
|
||||
g_assert(!nm_hostname_is_valid("fooBAR.com.", FALSE));
|
||||
g_assert(!nm_hostname_is_valid("fööbar", FALSE));
|
||||
g_assert(!nm_hostname_is_valid("", FALSE));
|
||||
g_assert(!nm_hostname_is_valid(".", FALSE));
|
||||
g_assert(!nm_hostname_is_valid("..", FALSE));
|
||||
g_assert(!nm_hostname_is_valid("foobar.", FALSE));
|
||||
g_assert(!nm_hostname_is_valid(".foobar", FALSE));
|
||||
g_assert(!nm_hostname_is_valid("foo..bar", FALSE));
|
||||
g_assert(!nm_hostname_is_valid("foo.bar..", FALSE));
|
||||
g_assert(
|
||||
!nm_hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
FALSE));
|
||||
g_assert(!nm_hostname_is_valid(
|
||||
"au-xph5-rvgrdsb5hcxc-47et3a5vvkrc-server-wyoz4elpdpe3.openstack.local",
|
||||
FALSE));
|
||||
|
||||
g_assert(nm_hostname_is_valid("foobar", TRUE));
|
||||
g_assert(nm_hostname_is_valid("foobar.com", TRUE));
|
||||
g_assert(nm_hostname_is_valid("foobar.com.", TRUE));
|
||||
g_assert(nm_hostname_is_valid("fooBAR", TRUE));
|
||||
g_assert(nm_hostname_is_valid("fooBAR.com", TRUE));
|
||||
g_assert(!nm_hostname_is_valid("fooBAR.", TRUE));
|
||||
g_assert(nm_hostname_is_valid("fooBAR.com.", TRUE));
|
||||
g_assert(!nm_hostname_is_valid("fööbar", TRUE));
|
||||
g_assert(!nm_hostname_is_valid("", TRUE));
|
||||
g_assert(!nm_hostname_is_valid(".", TRUE));
|
||||
g_assert(!nm_hostname_is_valid("..", TRUE));
|
||||
g_assert(!nm_hostname_is_valid("foobar.", TRUE));
|
||||
g_assert(!nm_hostname_is_valid(".foobar", TRUE));
|
||||
g_assert(!nm_hostname_is_valid("foo..bar", TRUE));
|
||||
g_assert(!nm_hostname_is_valid("foo.bar..", TRUE));
|
||||
g_assert(
|
||||
!nm_hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
TRUE));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE();
|
||||
|
||||
int
|
||||
|
|
@ -1590,6 +2184,16 @@ main(int argc, char **argv)
|
|||
g_test_add_func("/general/test_nm_g_source_sentinel", test_nm_g_source_sentinel);
|
||||
g_test_add_func("/general/test_nm_ascii", test_nm_ascii);
|
||||
g_test_add_func("/general/test_parse_env_file", test_parse_env_file);
|
||||
g_test_add_func("/general/test_unbase64char", test_unbase64char);
|
||||
g_test_add_func("/general/test_unbase64mem1", test_unbase64mem1);
|
||||
g_test_add_func("/general/test_unbase64mem2", test_unbase64mem2);
|
||||
g_test_add_func("/general/test_unbase64mem3", test_unbase64mem3);
|
||||
g_test_add_func("/general/test_path_compare", test_path_compare);
|
||||
g_test_add_func("/general/test_path_equal", test_path_equal);
|
||||
g_test_add_func("/general/test_path_find_first_component", test_path_find_first_component);
|
||||
g_test_add_func("/general/test_path_startswith", test_path_startswith);
|
||||
g_test_add_func("/general/test_path_simplify", test_path_simplify);
|
||||
g_test_add_func("/general/test_hostname_is_valid", test_hostname_is_valid);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ libnm_systemd_core = static_library(
|
|||
'src/libsystemd/sd-id128/id128-util.c',
|
||||
'src/libsystemd/sd-id128/sd-id128.c',
|
||||
'nm-sd.c',
|
||||
'nm-sd-utils-core.c',
|
||||
'sd-adapt-core/nm-sd-adapt-core.c',
|
||||
),
|
||||
include_directories: [
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2018 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "libnm-systemd-core/nm-default-systemd-core.h"
|
||||
|
||||
#include "nm-sd-utils-core.h"
|
||||
|
||||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
|
||||
#include "nm-sd-adapt-core.h"
|
||||
|
||||
#include "sd-id128.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMUuid *
|
||||
nm_sd_utils_id128_get_machine(NMUuid *out_uuid)
|
||||
{
|
||||
g_assert(out_uuid);
|
||||
|
||||
G_STATIC_ASSERT_EXPR(sizeof(*out_uuid) == sizeof(sd_id128_t));
|
||||
if (sd_id128_get_machine((sd_id128_t *) out_uuid) < 0)
|
||||
return NULL;
|
||||
return out_uuid;
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2018 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_SD_UTILS_CORE_H__
|
||||
#define __NM_SD_UTILS_CORE_H__
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct _NMUuid;
|
||||
|
||||
struct _NMUuid *nm_sd_utils_id128_get_machine(struct _NMUuid *out_uuid);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif /* __NM_SD_UTILS_CORE_H__ */
|
||||
|
|
@ -21,58 +21,6 @@ const bool mempool_use_allowed = true;
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nm_sd_utils_path_equal(const char *a, const char *b)
|
||||
{
|
||||
return path_equal(a, b);
|
||||
}
|
||||
|
||||
char *
|
||||
nm_sd_utils_path_simplify(char *path)
|
||||
{
|
||||
return path_simplify(path);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_sd_utils_path_startswith(const char *path, const char *prefix)
|
||||
{
|
||||
return path_startswith(path, prefix);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
nm_sd_utils_unbase64char(char ch, gboolean accept_padding_equal)
|
||||
{
|
||||
if (ch == '=' && accept_padding_equal)
|
||||
return G_MAXINT;
|
||||
return unbase64char(ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_sd_utils_unbase64mem:
|
||||
* @p: a valid base64 string. Whitespace is ignored, but invalid encodings
|
||||
* will cause the function to fail.
|
||||
* @l: the length of @p. @p is not treated as NUL terminated string but
|
||||
* merely as a buffer of ascii characters.
|
||||
* @secure: whether the temporary memory will be cleared to avoid leaving
|
||||
* secrets in memory (see also nm_explicit_bzero()).
|
||||
* @mem: (transfer full): the decoded buffer on success.
|
||||
* @len: the length of @mem on success.
|
||||
*
|
||||
* glib provides g_base64_decode(), but that does not report any errors
|
||||
* from invalid encodings. Expose systemd's implementation which does
|
||||
* reject invalid inputs.
|
||||
*
|
||||
* Returns: a non-negative code on success. Invalid encoding let the
|
||||
* function fail.
|
||||
*/
|
||||
int
|
||||
nm_sd_utils_unbase64mem(const char *p, size_t l, gboolean secure, guint8 **mem, size_t *len)
|
||||
{
|
||||
return unbase64mem_full(p, l, secure, (void **) mem, len);
|
||||
}
|
||||
|
||||
int
|
||||
nm_sd_dns_name_to_wire_format(const char *domain, guint8 *buffer, size_t len, gboolean canonical)
|
||||
{
|
||||
|
|
@ -85,14 +33,6 @@ nm_sd_dns_name_is_valid(const char *s)
|
|||
return dns_name_is_valid(s);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_sd_hostname_is_valid(const char *s, bool allow_trailing_dot)
|
||||
{
|
||||
return hostname_is_valid(s,
|
||||
allow_trailing_dot ? VALID_HOSTNAME_TRAILING_DOT
|
||||
: (ValidHostnameFlags) 0);
|
||||
}
|
||||
|
||||
char *
|
||||
nm_sd_dns_name_normalize(const char *s)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,25 +8,10 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean nm_sd_utils_path_equal(const char *a, const char *b);
|
||||
|
||||
char *nm_sd_utils_path_simplify(char *path);
|
||||
|
||||
const char *nm_sd_utils_path_startswith(const char *path, const char *prefix);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int nm_sd_utils_unbase64char(char ch, gboolean accept_padding_equal);
|
||||
|
||||
int nm_sd_utils_unbase64mem(const char *p, size_t l, gboolean secure, guint8 **mem, size_t *len);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
nm_sd_dns_name_to_wire_format(const char *domain, guint8 *buffer, size_t len, gboolean canonical);
|
||||
|
||||
int nm_sd_dns_name_is_valid(const char *s);
|
||||
gboolean nm_sd_hostname_is_valid(const char *s, bool allow_trailing_dot);
|
||||
int nm_sd_dns_name_is_valid(const char *s);
|
||||
|
||||
char *nm_sd_dns_name_normalize(const char *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
#include "libnm-log-core/nm-logging.h"
|
||||
#include "libnm-core-intern/nm-core-internal.h"
|
||||
#include "nm-initrd-generator.h"
|
||||
#include "libnm-systemd-shared/nm-sd-utils-shared.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -586,7 +585,7 @@ reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument)
|
|||
}
|
||||
}
|
||||
|
||||
if (client_hostname && !nm_sd_hostname_is_valid(client_hostname, FALSE))
|
||||
if (client_hostname && !nm_hostname_is_valid(client_hostname, FALSE))
|
||||
client_hostname = NULL;
|
||||
|
||||
if (client_hostname) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue