summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2018-03-15 17:27:07 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2018-03-15 17:27:07 +0100
commit32a279ea5f0ba7e1a5dcce2b76bd0775f295cc88 (patch)
treeee5905f08fdc184457b0539f2404d898ea55518b
parentb6059158b5330883c0ed7f80768b9dd155b93fca (diff)
parent0e4b33ee7552b036332f1bdbfed78f8ee75f000e (diff)
downloadNetworkManager-32a279ea5f0ba7e1a5dcce2b76bd0775f295cc88.tar.gz
dhcp: merge branch 'bg/dhcp-client-id-bgo793957'
https://bugzilla.gnome.org/show_bug.cgi?id=793957
-rw-r--r--NEWS11
-rw-r--r--src/dhcp/nm-dhcp-dhclient-utils.c48
-rw-r--r--src/dhcp/tests/test-dhcp-dhclient.c115
3 files changed, 156 insertions, 18 deletions
diff --git a/NEWS b/NEWS
index ede606e5c7..bdb7a45166 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,14 @@
+=============================================
+NetworkManager-1.?? (not released yet)
+Overview of changes since NetworkManager-1.10
+=============================================
+
+* A non-hexadecimal DHCPv4 client-id is now properly passed to
+ dhclient with the first byte (type) set to zero, as stated in the
+ documentation. This represents a change in behavior since previous
+ versions where the first character of the string was used as
+ type. The internal client is not affected by the change.
+
============================================
NetworkManager-1.10
Overview of changes since NetworkManager-1.8
diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c
index 1116e7514e..70d70fd60a 100644
--- a/src/dhcp/nm-dhcp-dhclient-utils.c
+++ b/src/dhcp/nm-dhcp-dhclient-utils.c
@@ -125,7 +125,7 @@ add_ip4_config (GString *str, GBytes *client_id, const char *hostname, gboolean
* as long as all the characters are printable.
*/
for (i = 1; (p[0] == 0) && i < l; i++) {
- if (!g_ascii_isprint (p[i]))
+ if (!g_ascii_isprint (p[i]) || p[i] == '\\' || p[i] == '"')
break;
}
@@ -138,8 +138,9 @@ add_ip4_config (GString *str, GBytes *client_id, const char *hostname, gboolean
g_string_append_printf (str, "%02x", (guint8) p[i]);
}
} else {
- /* Printable; just add to the line minus the 'type' */
+ /* Printable; just add to the line with type 0 */
g_string_append_c (str, '"');
+ g_string_append (str, "\\x00");
g_string_append_len (str, p + 1, l - 1);
g_string_append_c (str, '"');
}
@@ -177,31 +178,60 @@ read_client_id (const char *str)
{
gs_free char *s = NULL;
char *p;
+ int i = 0, j = 0;
nm_assert (!strncmp (str, CLIENTID_TAG, NM_STRLEN (CLIENTID_TAG)));
-
str += NM_STRLEN (CLIENTID_TAG);
+
+ if (!g_ascii_isspace (*str))
+ return NULL;
while (g_ascii_isspace (*str))
str++;
if (*str == '"') {
+ /* Parse string literal with escape sequences */
s = g_strdup (str + 1);
p = strrchr (s, '"');
if (p)
*p = '\0';
else
return NULL;
- } else
- s = g_strdup (str);
+ if (!s[0])
+ return NULL;
+
+ while (s[i]) {
+ if ( s[i] == '\\'
+ && s[i + 1] == 'x'
+ && g_ascii_isxdigit (s[i + 2])
+ && g_ascii_isxdigit (s[i + 3])) {
+ s[j++] = (g_ascii_xdigit_value (s[i + 2]) << 4)
+ + g_ascii_xdigit_value (s[i + 3]);
+ i += 4;
+ continue;
+ }
+ if ( s[i] == '\\'
+ && s[i + 1] >= '0' && s[i + 1] <= '7'
+ && s[1 + 2] >= '0' && s[i + 2] <= '7'
+ && s[1 + 3] >= '0' && s[i + 3] <= '7') {
+ s[j++] = ((s[i + 1] - '0') << 6)
+ + ((s[i + 2] - '0') << 3)
+ + ( s[i + 3] - '0');
+ i += 4;
+ continue;
+ }
+ s[j++] = s[i++];
+ }
+ return g_bytes_new_take (g_steal_pointer (&s), j);
+ }
+
+ /* Otherwise, try to read a hexadecimal sequence */
+ s = g_strdup (str);
g_strchomp (s);
if (s[strlen (s) - 1] == ';')
s[strlen (s) - 1] = '\0';
- if (!s[0])
- return NULL;
-
- return nm_dhcp_utils_client_id_string_to_bytes (s);
+ return nm_utils_hexstr2bin (s);
}
GBytes *
diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c
index d092dba44f..f1b0a1a1b1 100644
--- a/src/dhcp/tests/test-dhcp-dhclient.c
+++ b/src/dhcp/tests/test-dhcp-dhclient.c
@@ -154,7 +154,7 @@ test_override_client_id (void)
static const char *quote_client_id_expected = \
"# Created by NetworkManager\n"
"\n"
- "send dhcp-client-identifier \"1234\"; # added by NetworkManager\n"
+ "send dhcp-client-identifier \"\\x00abcd\"; # added by NetworkManager\n"
"\n"
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
@@ -172,7 +172,65 @@ test_quote_client_id (void)
{
test_config (NULL, quote_client_id_expected,
AF_INET, NULL, 0, FALSE,
- "1234",
+ "abcd",
+ NULL,
+ "eth0",
+ NULL);
+}
+
+/*****************************************************************************/
+
+static const char *quote_client_id_expected_2 = \
+ "# Created by NetworkManager\n"
+ "\n"
+ "send dhcp-client-identifier 00:61:5c:62:63; # added by NetworkManager\n"
+ "\n"
+ "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
+ "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
+ "option wpad code 252 = string;\n"
+ "\n"
+ "also request rfc3442-classless-static-routes;\n"
+ "also request ms-classless-static-routes;\n"
+ "also request static-routes;\n"
+ "also request wpad;\n"
+ "also request ntp-servers;\n"
+ "\n";
+
+static void
+test_quote_client_id_2 (void)
+{
+ test_config (NULL, quote_client_id_expected_2,
+ AF_INET, NULL, 0, FALSE,
+ "a\\bc",
+ NULL,
+ "eth0",
+ NULL);
+}
+
+/*****************************************************************************/
+
+static const char *hex_zero_client_id_expected = \
+ "# Created by NetworkManager\n"
+ "\n"
+ "send dhcp-client-identifier 00:11:22:33; # added by NetworkManager\n"
+ "\n"
+ "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
+ "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
+ "option wpad code 252 = string;\n"
+ "\n"
+ "also request rfc3442-classless-static-routes;\n"
+ "also request ms-classless-static-routes;\n"
+ "also request static-routes;\n"
+ "also request wpad;\n"
+ "also request ntp-servers;\n"
+ "\n";
+
+static void
+test_hex_zero_client_id (void)
+{
+ test_config (NULL, hex_zero_client_id_expected,
+ AF_INET, NULL, 0, FALSE,
+ "00:11:22:33",
NULL,
"eth0",
NULL);
@@ -183,7 +241,7 @@ test_quote_client_id (void)
static const char *ascii_client_id_expected = \
"# Created by NetworkManager\n"
"\n"
- "send dhcp-client-identifier \"qb:cd:ef:12:34:56\"; # added by NetworkManager\n"
+ "send dhcp-client-identifier \"\\x00qb:cd:ef:12:34:56\"; # added by NetworkManager\n"
"\n"
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
@@ -239,13 +297,13 @@ test_hex_single_client_id (void)
/*****************************************************************************/
static const char *existing_hex_client_id_orig = \
- "send dhcp-client-identifier 00:30:04:20:7A:08;\n";
+ "send dhcp-client-identifier 10:30:04:20:7A:08;\n";
static const char *existing_hex_client_id_expected = \
"# Created by NetworkManager\n"
"# Merged from /path/to/dhclient.conf\n"
"\n"
- "send dhcp-client-identifier 00:30:04:20:7A:08;\n"
+ "send dhcp-client-identifier 10:30:04:20:7A:08;\n"
"\n"
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
@@ -262,7 +320,7 @@ static void
test_existing_hex_client_id (void)
{
gs_unref_bytes GBytes *new_client_id = NULL;
- const guint8 bytes[] = { 0x00, 0x30, 0x04,0x20, 0x7A, 0x08 };
+ const guint8 bytes[] = { 0x10, 0x30, 0x04, 0x20, 0x7A, 0x08 };
new_client_id = g_bytes_new (bytes, sizeof (bytes));
test_config (existing_hex_client_id_orig, existing_hex_client_id_expected,
@@ -275,16 +333,52 @@ test_existing_hex_client_id (void)
/*****************************************************************************/
+static const char *existing_escaped_client_id_orig = \
+ "send dhcp-client-identifier \"\\044test\\xfe\";\n";
+
+static const char *existing_escaped_client_id_expected = \
+ "# Created by NetworkManager\n"
+ "# Merged from /path/to/dhclient.conf\n"
+ "\n"
+ "send dhcp-client-identifier \"\\044test\\xfe\";\n"
+ "\n"
+ "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
+ "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
+ "option wpad code 252 = string;\n"
+ "\n"
+ "also request rfc3442-classless-static-routes;\n"
+ "also request ms-classless-static-routes;\n"
+ "also request static-routes;\n"
+ "also request wpad;\n"
+ "also request ntp-servers;\n"
+ "\n";
+
+static void
+test_existing_escaped_client_id (void)
+{
+ gs_unref_bytes GBytes *new_client_id = NULL;
+
+ new_client_id = g_bytes_new ("$test\xfe", 6);
+ test_config (existing_escaped_client_id_orig, existing_escaped_client_id_expected,
+ AF_INET, NULL, 0, FALSE,
+ NULL,
+ new_client_id,
+ "eth0",
+ NULL);
+}
+
+/*****************************************************************************/
+
#define EACID "qb:cd:ef:12:34:56"
static const char *existing_ascii_client_id_orig = \
- "send dhcp-client-identifier \"" EACID "\";\n";
+ "send dhcp-client-identifier \"\\x00" EACID "\";\n";
static const char *existing_ascii_client_id_expected = \
"# Created by NetworkManager\n"
"# Merged from /path/to/dhclient.conf\n"
"\n"
- "send dhcp-client-identifier \"" EACID "\";\n"
+ "send dhcp-client-identifier \"\\x00" EACID "\";\n"
"\n"
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
@@ -1035,10 +1129,13 @@ main (int argc, char **argv)
g_test_add_func ("/dhcp/dhclient/orig_missing", test_orig_missing);
g_test_add_func ("/dhcp/dhclient/override_client_id", test_override_client_id);
- g_test_add_func ("/dhcp/dhclient/quote_client_id", test_quote_client_id);
+ g_test_add_func ("/dhcp/dhclient/quote_client_id/1", test_quote_client_id);
+ g_test_add_func ("/dhcp/dhclient/quote_client_id/2", test_quote_client_id_2);
+ g_test_add_func ("/dhcp/dhclient/hex_zero_client_id", test_hex_zero_client_id);
g_test_add_func ("/dhcp/dhclient/ascii_client_id", test_ascii_client_id);
g_test_add_func ("/dhcp/dhclient/hex_single_client_id", test_hex_single_client_id);
g_test_add_func ("/dhcp/dhclient/existing-hex-client-id", test_existing_hex_client_id);
+ g_test_add_func ("/dhcp/dhclient/existing-client-id", test_existing_escaped_client_id);
g_test_add_func ("/dhcp/dhclient/existing-ascii-client-id", test_existing_ascii_client_id);
g_test_add_func ("/dhcp/dhclient/fqdn", test_fqdn);
g_test_add_func ("/dhcp/dhclient/fqdn_options_override", test_fqdn_options_override);