summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-07-31 08:52:21 +0200
committerThomas Haller <thaller@redhat.com>2020-08-05 12:47:55 +0200
commit5da502a1e1bc8473686c2f20ff0ddbf268609c03 (patch)
treebcd42479f98c313c93c7bba7659a259dfdbe2a22
parent00c6823ecc3a3972e1c68234b19cdf9ea9b3fe2c (diff)
downloadNetworkManager-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.c78
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.h6
-rw-r--r--shared/nm-glib-aux/tests/test-shared-general.c32
-rw-r--r--src/nm-core-utils.c14
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 {