mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-19 19:00:38 +01:00
libnm/vpn: merge branch 'th/read-vpn-plugins-tests'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/30
This commit is contained in:
commit
f120bbc7a8
6 changed files with 291 additions and 3 deletions
|
|
@ -19,6 +19,10 @@
|
|||
/* Gettext package */
|
||||
#mesondefine GETTEXT_PACKAGE
|
||||
|
||||
/* Define to 1 if you have the declaration of `memfd_create', and to 0 if you
|
||||
don't. */
|
||||
#mesondefine HAVE_DECL_MEMFD_CREATE
|
||||
|
||||
/* Define to 1 if you have the declaration of `reallocarray', and to 0 if
|
||||
you don't. */
|
||||
#mesondefine HAVE_DECL_REALLOCARRAY
|
||||
|
|
|
|||
|
|
@ -81,6 +81,12 @@ AC_CHECK_DECLS([
|
|||
#include <malloc.h>
|
||||
]])
|
||||
|
||||
AC_CHECK_DECLS([
|
||||
memfd_create],
|
||||
[], [], [[
|
||||
#include <sys/mman.h>
|
||||
]])
|
||||
|
||||
AC_CHECK_HEADERS(sys/auxv.h)
|
||||
|
||||
AC_CHECK_DECLS([getrandom],
|
||||
|
|
|
|||
|
|
@ -810,15 +810,14 @@ nm_vpn_service_plugin_read_vpn_details (int fd,
|
|||
|
||||
errno = 0;
|
||||
nr = read (fd, &c, 1);
|
||||
if (nr == -1) {
|
||||
if (nr < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
g_usleep (100);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (c != '\n') {
|
||||
if (nr > 0 && c != '\n') {
|
||||
g_string_append_c (line, c);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -879,6 +878,9 @@ nm_vpn_service_plugin_read_vpn_details (int fd,
|
|||
}
|
||||
|
||||
g_string_truncate (line, 0);
|
||||
|
||||
if (nr == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (success) {
|
||||
|
|
|
|||
|
|
@ -20,8 +20,16 @@
|
|||
|
||||
#include "nm-default.h"
|
||||
|
||||
#if defined (HAVE_DECL_MEMFD_CREATE) && HAVE_DECL_MEMFD_CREATE
|
||||
#include <linux/memfd.h>
|
||||
#endif
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "nm-libnm-utils.h"
|
||||
|
||||
#include "nm-vpn-service-plugin.h"
|
||||
|
||||
#include "nm-utils/nm-test-utils.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -2158,6 +2166,271 @@ test_fixup_product_string (void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
_memfd_create (const char *name)
|
||||
{
|
||||
#if defined (HAVE_DECL_MEMFD_CREATE) && HAVE_DECL_MEMFD_CREATE
|
||||
return memfd_create (name, MFD_CLOEXEC);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *key;
|
||||
const char *val;
|
||||
} ReadVpnDetailData;
|
||||
|
||||
#define READ_VPN_DETAIL_DATA(...) \
|
||||
((ReadVpnDetailData []) { __VA_ARGS__ })
|
||||
|
||||
static gboolean
|
||||
_do_read_vpn_details_impl1 (const char *file,
|
||||
int line,
|
||||
int memfd,
|
||||
char *mem,
|
||||
gsize len,
|
||||
const ReadVpnDetailData *expected_data,
|
||||
guint expected_data_len,
|
||||
const ReadVpnDetailData *expected_secrets,
|
||||
guint expected_secrets_len)
|
||||
{
|
||||
gssize written;
|
||||
off_t lseeked;
|
||||
gs_unref_hashtable GHashTable *data = NULL;
|
||||
gs_unref_hashtable GHashTable *secrets = NULL;
|
||||
|
||||
written = write (memfd, mem, len);
|
||||
g_assert_cmpint (written, ==, (gssize) len);
|
||||
|
||||
lseeked = lseek (memfd, 0, SEEK_SET);
|
||||
g_assert_cmpint (lseeked, ==, 0);
|
||||
|
||||
if (!nm_vpn_service_plugin_read_vpn_details (memfd,
|
||||
&data,
|
||||
&secrets)) {
|
||||
g_assert (!data);
|
||||
g_assert (!secrets);
|
||||
g_assert_cmpint (expected_data_len, ==, 0);
|
||||
g_assert_cmpint (expected_secrets_len, ==, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define _assert_hash(hash, expected, expected_len) \
|
||||
G_STMT_START { \
|
||||
GHashTable *_hash = (hash); \
|
||||
guint _expected_len = (expected_len); \
|
||||
const ReadVpnDetailData *_expected = (expected); \
|
||||
GHashTableIter _iter; \
|
||||
const char *_k, *_v; \
|
||||
guint _i; \
|
||||
\
|
||||
g_assert (_hash); \
|
||||
\
|
||||
g_hash_table_iter_init (&_iter, _hash); \
|
||||
while (g_hash_table_iter_next (&_iter, (gpointer *) &_k, (gpointer *) &_v)) { \
|
||||
for (_i = 0; _i < _expected_len; _i++) { \
|
||||
if (nm_streq (_expected[_i].key, _k)) \
|
||||
break; \
|
||||
} \
|
||||
if (_i >= _expected_len) \
|
||||
g_error ("%s:%d: hash '%s' contains unexpected data key '%s' with value '%s'", file, line, G_STRINGIFY (hash), _k, _v); \
|
||||
} \
|
||||
\
|
||||
for (_i = 0; _i < _expected_len; _i++) { \
|
||||
const ReadVpnDetailData *_d = &_expected[_i]; \
|
||||
\
|
||||
g_assert (_d->key); \
|
||||
g_assert (_d->val); \
|
||||
_v = g_hash_table_lookup (_hash, _d->key); \
|
||||
if (!nm_streq0 (_v, _d->val)) \
|
||||
g_error ("%s:%d: hash '%s' contains data key '%s' with value %s%s%s but we expected '%s'", file, line, G_STRINGIFY (hash), _d->key, NM_PRINT_FMT_QUOTE_STRING (_v), _d->val); \
|
||||
} \
|
||||
\
|
||||
g_assert_cmpint (g_hash_table_size (_hash), ==, _expected_len); \
|
||||
} G_STMT_END
|
||||
|
||||
_assert_hash (data, expected_data, expected_data_len);
|
||||
_assert_hash (secrets, expected_secrets, expected_secrets_len);
|
||||
|
||||
#undef _assert_hash
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define _do_read_vpn_details_impl0(str, expected_data, expected_data_len, expected_secrets, expected_secrets_len, pre_setup_cmd) \
|
||||
G_STMT_START { \
|
||||
nm_auto_close int _memfd = _memfd_create ("libnm-test-read-vpn-details"); \
|
||||
\
|
||||
if (_memfd < 0) \
|
||||
g_test_skip ("cannot create memfd"); \
|
||||
else { \
|
||||
{ pre_setup_cmd ; } \
|
||||
_do_read_vpn_details_impl1 (__FILE__, \
|
||||
__LINE__, \
|
||||
_memfd, \
|
||||
""str"", \
|
||||
NM_STRLEN (str), \
|
||||
expected_data, \
|
||||
expected_data_len, \
|
||||
expected_secrets, \
|
||||
expected_secrets_len); \
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
||||
#define _do_read_vpn_details_empty(str) \
|
||||
_do_read_vpn_details_impl0 (str, \
|
||||
NULL, \
|
||||
0, \
|
||||
NULL, \
|
||||
0, \
|
||||
{ } )
|
||||
|
||||
#define _do_read_vpn_details(str, expected_data, expected_secrets, pre_setup_cmd) \
|
||||
_do_read_vpn_details_impl0 (str, \
|
||||
expected_data, \
|
||||
G_N_ELEMENTS (expected_data), \
|
||||
expected_secrets, \
|
||||
G_N_ELEMENTS (expected_secrets), \
|
||||
pre_setup_cmd)
|
||||
|
||||
static void
|
||||
test_nm_vpn_service_plugin_read_vpn_details (void)
|
||||
{
|
||||
_do_read_vpn_details_empty ("");
|
||||
_do_read_vpn_details_empty ("hallo");
|
||||
_do_read_vpn_details_empty ("DONE");
|
||||
_do_read_vpn_details_empty ("DONE\n");
|
||||
_do_read_vpn_details_empty ("DONE\0");
|
||||
_do_read_vpn_details_empty ("\0DONE\0");
|
||||
|
||||
_do_read_vpn_details (""
|
||||
"DATA_KEY=some-key\n"
|
||||
"DATA_VAL=string\n"
|
||||
"\n"
|
||||
"DATA_KEY=some-other-key\n"
|
||||
"DATA_VAL=val2\n"
|
||||
"\n"
|
||||
"SECRET_KEY=some-secret\n"
|
||||
"SECRET_VAL=val3\n"
|
||||
"\n"
|
||||
"DONE\n"
|
||||
"\n"
|
||||
"",
|
||||
READ_VPN_DETAIL_DATA (
|
||||
{ "some-key", "string" },
|
||||
{ "some-other-key", "val2" },
|
||||
),
|
||||
READ_VPN_DETAIL_DATA (
|
||||
{ "some-secret", "val3" },
|
||||
),
|
||||
);
|
||||
|
||||
_do_read_vpn_details (""
|
||||
"DATA_KEY=some-key\n"
|
||||
"DATA_VAL=string\n"
|
||||
"DONE\n",
|
||||
READ_VPN_DETAIL_DATA (
|
||||
{ "some-key", "string" },
|
||||
),
|
||||
READ_VPN_DETAIL_DATA (),
|
||||
);
|
||||
|
||||
_do_read_vpn_details (""
|
||||
"DATA_KEY=some-key\n"
|
||||
"DATA_VAL=string\n"
|
||||
"=continued after a line break\n"
|
||||
"SECRET_KEY=key names\n"
|
||||
"=can have\n"
|
||||
"=continuations too\n"
|
||||
"bogus1=\n"
|
||||
"SECRET_VAL=value\n"
|
||||
"bogus=value\n"
|
||||
"bogus=\n"
|
||||
"DATA_VAL=x\n"
|
||||
"DATA_KEY=\n"
|
||||
"DATA_VAL=\n"
|
||||
"DATA_VAL=y\n"
|
||||
"DATA_KEY=y\n"
|
||||
"DATA_KEY=y\n"
|
||||
"DATA_KEY=z\n"
|
||||
"SECRET_KEY=s1\n"
|
||||
"DATA_VAL=z\n"
|
||||
"SECRET_VAL=S1\n"
|
||||
"\n"
|
||||
"DONE\n"
|
||||
"",
|
||||
READ_VPN_DETAIL_DATA (
|
||||
{ "some-key", "string\ncontinued after a line break" },
|
||||
),
|
||||
READ_VPN_DETAIL_DATA (
|
||||
{ "key names\ncan have\ncontinuations too", "value" },
|
||||
),
|
||||
NMTST_EXPECT_LIBNM_WARNING ("DATA_VAL= not preceded by DATA_KEY=")
|
||||
);
|
||||
|
||||
_do_read_vpn_details (""
|
||||
"DATA_KEY=some-key\n"
|
||||
"DATA_VAL=string\n"
|
||||
"=continued after a line break\n"
|
||||
"SECRET_KEY=key names\n"
|
||||
"=can have\n"
|
||||
"=continuations too\n"
|
||||
"SECRET_VAL=value\n"
|
||||
"",
|
||||
READ_VPN_DETAIL_DATA (
|
||||
{ "some-key", "string\ncontinued after a line break" },
|
||||
),
|
||||
READ_VPN_DETAIL_DATA (
|
||||
{ "key names\ncan have\ncontinuations too", "value" },
|
||||
),
|
||||
);
|
||||
|
||||
_do_read_vpn_details (""
|
||||
"DATA_KEY=some-key\n"
|
||||
"DATA_VAL=string\n"
|
||||
"\n"
|
||||
"DATA_KEY=some\n"
|
||||
"=key-2\n"
|
||||
"DATA_VAL=val2\n"
|
||||
"\n"
|
||||
"DATA_KEY=key3\0"
|
||||
"=key-2\n"
|
||||
"DATA_VAL=val3\n"
|
||||
"\n"
|
||||
"SECRET_KEY=some-secret\n"
|
||||
"SECRET_VAL=val3\n"
|
||||
"\n"
|
||||
"SECRET_KEY=\n"
|
||||
"SECRET_VAL=val3\n"
|
||||
"\n"
|
||||
"SECRET_KEY=keyx\n"
|
||||
"SECRET_VAL=\n"
|
||||
"\n"
|
||||
"SECRET_KEY=ke\xc0yx\n"
|
||||
"SECRET_VAL=inval\n"
|
||||
"\n"
|
||||
"SECRET_KEY=key-inval\n"
|
||||
"SECRET_VAL=in\xc1val\n"
|
||||
"\n"
|
||||
"DONE\n"
|
||||
"\n"
|
||||
"",
|
||||
READ_VPN_DETAIL_DATA (
|
||||
{ "some\nkey-2", "val2" },
|
||||
{ "some-key", "string" },
|
||||
{ "key3", "val3" },
|
||||
),
|
||||
READ_VPN_DETAIL_DATA (
|
||||
{ "some-secret", "val3" },
|
||||
{ "", "val3" },
|
||||
{ "keyx", "" },
|
||||
{ "ke\xc0yx", "inval" },
|
||||
{ "key-inval", "in\xc1val" },
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
||||
int main (int argc, char **argv)
|
||||
|
|
@ -2166,6 +2439,7 @@ int main (int argc, char **argv)
|
|||
|
||||
g_test_add_func ("/libnm/general/fixup_product_string", test_fixup_product_string);
|
||||
g_test_add_func ("/libnm/general/fixup_vendor_string", test_fixup_vendor_string);
|
||||
g_test_add_func ("/libnm/general/nm_vpn_service_plugin_read_vpn_details", test_nm_vpn_service_plugin_read_vpn_details);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ config_h.set('HAVE_SECURE_GETENV', cc.has_function('secure_getenv'))
|
|||
config_h.set('HAVE___SECURE_GETENV', cc.has_function('__secure_getenv'))
|
||||
config_h.set10('HAVE_DECL_REALLOCARRAY', cc.has_function('reallocarray', prefix: '#include <malloc.h>'))
|
||||
config_h.set10('HAVE_DECL_EXPLICIT_BZERO', cc.has_function('explicit_bzero', prefix: '#include <string.h>'))
|
||||
config_h.set10('HAVE_DECL_MEMFD_CREATE', cc.has_function('memfd_create', prefix: '#include <sys/mman.h>'))
|
||||
|
||||
# types
|
||||
config_h.set('SIZEOF_DEV_T', cc.sizeof('dev_t', prefix: '#include <sys/types.h>'))
|
||||
|
|
|
|||
|
|
@ -700,6 +700,7 @@ nmtst_test_quick (void)
|
|||
#else
|
||||
#define NMTST_EXPECT_LIBNM(level, msg) NMTST_EXPECT ("libnm", level, msg)
|
||||
|
||||
#define NMTST_EXPECT_LIBNM_WARNING(msg) NMTST_EXPECT_LIBNM (G_LOG_LEVEL_WARNING, msg)
|
||||
#define NMTST_EXPECT_LIBNM_CRITICAL(msg) NMTST_EXPECT_LIBNM (G_LOG_LEVEL_CRITICAL, msg)
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue