diff options
author | Thomas Haller <thaller@redhat.com> | 2020-07-31 08:52:21 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-08-05 12:47:55 +0200 |
commit | 5da502a1e1bc8473686c2f20ff0ddbf268609c03 (patch) | |
tree | bcd42479f98c313c93c7bba7659a259dfdbe2a22 | |
parent | 00c6823ecc3a3972e1c68234b19cdf9ea9b3fe2c (diff) | |
download | NetworkManager-5da502a1e1bc8473686c2f20ff0ddbf268609c03.tar.gz |
shared,core: extend nm_utils_is_specific_hostname() and move to shared
nm_utils_is_specific_hostname() is basically to check whether the
hostname is localhost (and also handle "(null)").
In that sense, it's similar to systemd's is_localhost(). Extend or
variant to
- be case insensitive (like is_localhost()).
- accept more variants of localhost/localdomain names as special.
-rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.c | 78 | ||||
-rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.h | 6 | ||||
-rw-r--r-- | shared/nm-glib-aux/tests/test-shared-general.c | 32 | ||||
-rw-r--r-- | src/nm-core-utils.c | 14 |
4 files changed, 116 insertions, 14 deletions
diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index 78496c3154..b973d8aafc 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -5157,3 +5157,81 @@ _nm_utils_format_variant_attributes (GHashTable *attributes, key_value_separator); return g_string_free (str, FALSE); } + +/*****************************************************************************/ + +gboolean +nm_utils_is_localhost (const char *name) +{ + static const char *const NAMES[] = { + "localhost", + "localhost4", + "localhost6", + "localhost.localdomain", + "localhost4.localdomain4", + "localhost6.localdomain6", + }; + gsize name_len; + int i; + + if (!name) + return FALSE; + + /* This tries to identify local host and domain names + * described in RFC6761 plus the redhatism of localdomain. + * + * Similar to systemd's is_localhost(). */ + + name_len = strlen (name); + + if (name_len == 0) + return FALSE; + + if (name[name_len - 1] == '.') { + /* one trailing dot is fine. Hide it. */ + name_len--; + } + + for (i = 0; i < (int) G_N_ELEMENTS (NAMES); i++) { + const char *n = NAMES[i]; + gsize l = strlen (n); + gsize s; + + if (name_len < l) + continue; + + s = name_len - l; + + if (g_ascii_strncasecmp (&name[s], n, l) != 0) + continue; + + /* we accept the name if it is equal to one of the well-known names, + * or if it is some prefix, a '.' and the well-known name. */ + if (s == 0) + return TRUE; + if (name[s - 1] == '.') + return TRUE; + } + + return FALSE; +} + +gboolean +nm_utils_is_specific_hostname (const char *name) +{ + if (nm_str_is_empty (name)) + return FALSE; + + if (nm_streq (name, "(none)")) { + /* This is not a special hostname. Probably an artefact by somebody wrongly + * printing NULL. */ + return FALSE; + } + + if (nm_utils_is_localhost (name)) + return FALSE; + + /* FIXME: properly validate the hostname, like systemd's hostname_is_valid() */ + + return TRUE; +} diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index 17884a356d..f9c76d880e 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -2195,4 +2195,10 @@ char *_nm_utils_format_variant_attributes (GHashTable *attributes, char attr_separator, char key_value_separator); +/*****************************************************************************/ + +gboolean nm_utils_is_localhost (const char *name); + +gboolean nm_utils_is_specific_hostname (const char *name); + #endif /* __NM_SHARED_UTILS_H__ */ diff --git a/shared/nm-glib-aux/tests/test-shared-general.c b/shared/nm-glib-aux/tests/test-shared-general.c index afccb969f0..9af5f2b050 100644 --- a/shared/nm-glib-aux/tests/test-shared-general.c +++ b/shared/nm-glib-aux/tests/test-shared-general.c @@ -910,6 +910,37 @@ test_in_strset_ascii_case (void) /*****************************************************************************/ +static void +test_is_specific_hostname (void) +{ + g_assert (!nm_utils_is_specific_hostname (NULL)); + g_assert (!nm_utils_is_specific_hostname ("")); + g_assert (!nm_utils_is_specific_hostname ("(none)")); + g_assert (nm_utils_is_specific_hostname ("(NONE)")); + + g_assert (!nm_utils_is_specific_hostname ("localhost")); + g_assert (!nm_utils_is_specific_hostname ("lOcalHost")); + g_assert (!nm_utils_is_specific_hostname ("LOCALHOST")); + + g_assert (!nm_utils_is_specific_hostname ("LOCALHOST.localdomain")); + + g_assert (nm_utils_is_specific_hostname ("xlocalhost")); + g_assert (nm_utils_is_specific_hostname ("lOcalHxost")); + g_assert (nm_utils_is_specific_hostname ("LOCALxHOST")); + + g_assert (!nm_utils_is_specific_hostname ("foo.LOCALHOST")); + g_assert (!nm_utils_is_specific_hostname ("foo.LOCALHOsT6.")); + g_assert (!nm_utils_is_specific_hostname ("foo.LOCALHOsT6.localdomain6")); + g_assert (!nm_utils_is_specific_hostname (".LOCALHOsT6.localdomain6")); + g_assert (!nm_utils_is_specific_hostname ("LOCALHOsT6.localdomain6")); + g_assert (!nm_utils_is_specific_hostname ("LOCALHOsT6.localdomain6.")); + g_assert (nm_utils_is_specific_hostname ("LOCALHOsT6.localdomain.")); + + g_assert (nm_utils_is_specific_hostname (" ")); +} + +/*****************************************************************************/ + NMTST_DEFINE (); int main (int argc, char **argv) @@ -933,6 +964,7 @@ int main (int argc, char **argv) g_test_add_func ("/general/test_nm_str_buf", test_nm_str_buf); g_test_add_func ("/general/test_nm_utils_parse_next_line", test_nm_utils_parse_next_line); g_test_add_func ("/general/test_in_strset_ascii_case", test_in_strset_ascii_case); + g_test_add_func ("/general/test_is_specific_hostname", test_is_specific_hostname); return g_test_run (); } diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 75e0941aa9..674f5de135 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -2373,20 +2373,6 @@ NM_ASSERT_VALID_PATH_COMPONENT (const char *name) g_assert_not_reached (); } -gboolean -nm_utils_is_specific_hostname (const char *name) -{ - if (!name) - return FALSE; - if ( strcmp (name, "(none)") - && strcmp (name, "localhost") - && strcmp (name, "localhost6") - && strcmp (name, "localhost.localdomain") - && strcmp (name, "localhost6.localdomain6")) - return TRUE; - return FALSE; -} - /*****************************************************************************/ typedef struct { |