Blame SOURCES/dns-domain-name-liberal.patch

3a7434
From e368c5a42656a687e6b726978752eb4abf6503d0 Mon Sep 17 00:00:00 2001
3a7434
From: Stef Walter <stefw@redhat.com>
3a7434
Date: Fri, 31 Jul 2015 12:53:04 +0200
3a7434
Subject: [PATCH 1/3] Be more liberal on what we accept as a domain name
3a7434
3a7434
Make the checks on what we accept as a domain name more liberal
3a7434
for values coming in from the network.
3a7434
3a7434
DNS Domain names are pretty liberal (internet domain names
3a7434
are more restrictive) See RFC 2181 section 11
3a7434
3a7434
http://www.ietf.org/rfc/rfc2181.txt
3a7434
3a7434
However we cannot consume names with whitespace and problematic
3a7434
punctuation, due to the various programs that parse the
3a7434
configuration files we set up.
3a7434
---
3a7434
 service/realm-disco-mscldap.c |  9 +++------
3a7434
 service/realm-disco-rootdse.c | 15 +++++++--------
3a7434
 service/realm-options.c       | 31 +++++++++++++++++++++++++++++++
3a7434
 service/realm-options.h       |  2 ++
3a7434
 4 files changed, 43 insertions(+), 14 deletions(-)
3a7434
3a7434
diff --git a/service/realm-disco-mscldap.c b/service/realm-disco-mscldap.c
3a7434
index 1ed4063..d3d3c10 100644
3a7434
--- a/service/realm-disco-mscldap.c
3a7434
+++ b/service/realm-disco-mscldap.c
3a7434
@@ -17,6 +17,7 @@
3a7434
 #include "realm-dbus-constants.h"
3a7434
 #include "realm-disco-mscldap.h"
3a7434
 #include "realm-ldap.h"
3a7434
+#include "realm-options.h"
3a7434
 
3a7434
 #include <glib/gi18n.h>
3a7434
 
3a7434
@@ -40,8 +41,6 @@ typedef struct {
3a7434
 #define HOST_NAME_MAX 255
3a7434
 #endif
3a7434
 
3a7434
-#define DOMAIN_NAME_VALID "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-."
3a7434
-
3a7434
 static void
3a7434
 closure_free (gpointer data)
3a7434
 {
3a7434
@@ -100,21 +99,19 @@ get_string (guchar *beg,
3a7434
             guchar **at)
3a7434
 {
3a7434
 	gchar buffer[HOST_NAME_MAX];
3a7434
-	gsize len;
3a7434
 	int n;
3a7434
 
3a7434
 	n = dn_expand (beg, end, *at, buffer, sizeof (buffer));
3a7434
 	if (n < 0)
3a7434
 		return NULL;
3a7434
 
3a7434
-	len = strlen (buffer);
3a7434
-	if (strspn (buffer, DOMAIN_NAME_VALID) != len) {
3a7434
+	if (!realm_options_check_domain_name (buffer)) {
3a7434
 		g_message ("received invalid NetLogon string characters");
3a7434
 		return NULL;
3a7434
 	}
3a7434
 
3a7434
 	(*at) += n;
3a7434
-	return g_strndup (buffer, len);
3a7434
+	return g_strdup (buffer);
3a7434
 }
3a7434
 
3a7434
 static gboolean
3a7434
diff --git a/service/realm-disco-rootdse.c b/service/realm-disco-rootdse.c
3a7434
index 1a80d98..3100650 100644
3a7434
--- a/service/realm-disco-rootdse.c
3a7434
+++ b/service/realm-disco-rootdse.c
3a7434
@@ -19,13 +19,12 @@
3a7434
 #include "realm-disco-mscldap.h"
3a7434
 #include "realm-disco-rootdse.h"
3a7434
 #include "realm-ldap.h"
3a7434
+#include "realm-options.h"
3a7434
 
3a7434
 #include <glib/gi18n.h>
3a7434
 
3a7434
 #include <resolv.h>
3a7434
 
3a7434
-#define DOMAIN_NAME_VALID "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-."
3a7434
-
3a7434
 typedef struct _Closure Closure;
3a7434
 
3a7434
 struct _Closure {
3a7434
@@ -92,7 +91,7 @@ static gchar *
3a7434
 entry_get_attribute (LDAP *ldap,
3a7434
                      LDAPMessage *entry,
3a7434
                      const gchar *field,
3a7434
-                     const gchar *valid)
3a7434
+                     gboolean domain_name)
3a7434
 {
3a7434
 	struct berval **bvs = NULL;
3a7434
 	gchar *value = NULL;
3a7434
@@ -102,8 +101,8 @@ entry_get_attribute (LDAP *ldap,
3a7434
 
3a7434
 	if (bvs && bvs[0]) {
3a7434
 		value = g_strndup (bvs[0]->bv_val, bvs[0]->bv_len);
3a7434
-		if (valid) {
3a7434
-		       if (strspn (value, valid) != bvs[0]->bv_len) {
3a7434
+		if (domain_name) {
3a7434
+		       if (!realm_options_check_domain_name (value)) {
3a7434
 			       g_free (value);
3a7434
 			       g_message ("Invalid value in LDAP %s field", field);
3a7434
 			       value = NULL;
3a7434
@@ -155,7 +154,7 @@ result_krb_realm (GTask *task,
3a7434
 	entry = ldap_first_entry (ldap, message);
3a7434
 
3a7434
 	g_free (clo->disco->kerberos_realm);
3a7434
-	clo->disco->kerberos_realm = entry_get_attribute (ldap, entry, "cn", DOMAIN_NAME_VALID);
3a7434
+	clo->disco->kerberos_realm = entry_get_attribute (ldap, entry, "cn", TRUE);
3a7434
 
3a7434
 	g_debug ("Found realm: %s", clo->disco->kerberos_realm);
3a7434
 
3a7434
@@ -211,7 +210,7 @@ result_domain_info (GTask *task,
3a7434
 
3a7434
 	/* What is the domain name? */
3a7434
 	g_free (clo->disco->domain_name);
3a7434
-	clo->disco->domain_name = entry_get_attribute (ldap, entry, "associatedDomain", DOMAIN_NAME_VALID);
3a7434
+	clo->disco->domain_name = entry_get_attribute (ldap, entry, "associatedDomain", TRUE);
3a7434
 
3a7434
 	g_debug ("Got associatedDomain: %s", clo->disco->domain_name);
3a7434
 
3a7434
@@ -310,7 +309,7 @@ result_root_dse (GTask *task,
3a7434
 	entry = ldap_first_entry (ldap, message);
3a7434
 
3a7434
 	/* Parse out the default naming context */
3a7434
-	clo->default_naming_context = entry_get_attribute (ldap, entry, "defaultNamingContext", NULL);
3a7434
+	clo->default_naming_context = entry_get_attribute (ldap, entry, "defaultNamingContext", FALSE);
3a7434
 
3a7434
 	g_debug ("Got defaultNamingContext: %s", clo->default_naming_context);
3a7434
 
3a7434
diff --git a/service/realm-options.c b/service/realm-options.c
3a7434
index 53266f6..bba3ee4 100644
3a7434
--- a/service/realm-options.c
3a7434
+++ b/service/realm-options.c
3a7434
@@ -18,6 +18,8 @@
3a7434
 #include "realm-options.h"
3a7434
 #include "realm-settings.h"
3a7434
 
3a7434
+#include <string.h>
3a7434
+
3a7434
 gboolean
3a7434
 realm_options_automatic_install (void)
3a7434
 {
3a7434
@@ -128,3 +130,32 @@ realm_options_qualify_names (const gchar *realm_name)
3a7434
 
3a7434
 	return qualify;
3a7434
 }
3a7434
+
3a7434
+gboolean
3a7434
+realm_options_check_domain_name (const gchar *name)
3a7434
+{
3a7434
+	/*
3a7434
+	 * DNS Domain names are pretty liberal (internet domain names
3a7434
+	 * are more restrictive) See RFC 2181 section 11
3a7434
+	 *
3a7434
+	 * http://www.ietf.org/rfc/rfc2181.txt
3a7434
+	 *
3a7434
+	 * However we cannot consume names with whitespace and problematic
3a7434
+	 * punctuation, due to the various programs that parse the
3a7434
+	 * configuration files we set up.
3a7434
+	 */
3a7434
+
3a7434
+	gsize i, len;
3a7434
+	static const gchar *invalid = "=[]:";
3a7434
+
3a7434
+	g_return_val_if_fail (name != NULL, FALSE);
3a7434
+
3a7434
+	for (i = 0, len = strlen (name); i < len; i++) {
3a7434
+		if (name[i] <= ' ')
3a7434
+			return FALSE;
3a7434
+		if (strchr (invalid, name[i]))
3a7434
+			return FALSE;
3a7434
+	}
3a7434
+
3a7434
+	return TRUE;
3a7434
+}
3a7434
diff --git a/service/realm-options.h b/service/realm-options.h
3a7434
index 52dc6ff..4890cba 100644
3a7434
--- a/service/realm-options.h
3a7434
+++ b/service/realm-options.h
3a7434
@@ -39,6 +39,8 @@ gboolean       realm_options_automatic_mapping        (GVariant *options,
3a7434
 
3a7434
 gboolean       realm_options_qualify_names            (const gchar *realm_name);
3a7434
 
3a7434
+gboolean       realm_options_check_domain_name        (const gchar *domain_name);
3a7434
+
3a7434
 G_END_DECLS
3a7434
 
3a7434
 #endif /* __REALM_OPTIONS_H__ */
3a7434
-- 
3a7434
2.4.3
3a7434