mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-06-11 13:08:19 +02:00
dhcp: dhclient: set type 0 for printable client IDs
The documentation for the ipv4.dhcp-client-id property says: If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. However, currently we set the client-id without the leading zero byte in the dhclient configuration and thus dhclient sends the first string character as type and the remainder as client-id content. Looking through git history, the dhclient plugin has always behaved this way even if the intent was clearly that string client-id had to be zero padded (this is evident by looking at nm_dhcp_utils_client_id_string_to_bytes()). The internal plugin instead sends the correct client-id with zero type. Change the dhclient plugin to honor the documented behavior and add the leading zero byte when the client-id is a string. This commit introduces a change in behavior for users that have dhcp=dhclient and have a plain string (not hexadecimal) set in ipv4.dhcp-client-id, as NM will send a different client-id possibly changing the IP address returned by the server. https://bugzilla.gnome.org/show_bug.cgi?id=793957
This commit is contained in:
parent
b6059158b5
commit
8ffa22d10d
3 changed files with 124 additions and 16 deletions
11
NEWS
11
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
|
NetworkManager-1.10
|
||||||
Overview of changes since NetworkManager-1.8
|
Overview of changes since NetworkManager-1.8
|
||||||
|
|
|
||||||
|
|
@ -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]);
|
g_string_append_printf (str, "%02x", (guint8) p[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} 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_c (str, '"');
|
||||||
|
g_string_append (str, "\\x00");
|
||||||
g_string_append_len (str, p + 1, l - 1);
|
g_string_append_len (str, p + 1, l - 1);
|
||||||
g_string_append_c (str, '"');
|
g_string_append_c (str, '"');
|
||||||
}
|
}
|
||||||
|
|
@ -177,31 +178,60 @@ read_client_id (const char *str)
|
||||||
{
|
{
|
||||||
gs_free char *s = NULL;
|
gs_free char *s = NULL;
|
||||||
char *p;
|
char *p;
|
||||||
|
int i = 0, j = 0;
|
||||||
|
|
||||||
nm_assert (!strncmp (str, CLIENTID_TAG, NM_STRLEN (CLIENTID_TAG)));
|
nm_assert (!strncmp (str, CLIENTID_TAG, NM_STRLEN (CLIENTID_TAG)));
|
||||||
|
|
||||||
str += NM_STRLEN (CLIENTID_TAG);
|
str += NM_STRLEN (CLIENTID_TAG);
|
||||||
|
|
||||||
|
if (!g_ascii_isspace (*str))
|
||||||
|
return NULL;
|
||||||
while (g_ascii_isspace (*str))
|
while (g_ascii_isspace (*str))
|
||||||
str++;
|
str++;
|
||||||
|
|
||||||
if (*str == '"') {
|
if (*str == '"') {
|
||||||
|
/* Parse string literal with escape sequences */
|
||||||
s = g_strdup (str + 1);
|
s = g_strdup (str + 1);
|
||||||
p = strrchr (s, '"');
|
p = strrchr (s, '"');
|
||||||
if (p)
|
if (p)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
else
|
else
|
||||||
return NULL;
|
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);
|
g_strchomp (s);
|
||||||
if (s[strlen (s) - 1] == ';')
|
if (s[strlen (s) - 1] == ';')
|
||||||
s[strlen (s) - 1] = '\0';
|
s[strlen (s) - 1] = '\0';
|
||||||
|
|
||||||
if (!s[0])
|
return nm_utils_hexstr2bin (s);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return nm_dhcp_utils_client_id_string_to_bytes (s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GBytes *
|
GBytes *
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ test_override_client_id (void)
|
||||||
static const char *quote_client_id_expected = \
|
static const char *quote_client_id_expected = \
|
||||||
"# Created by NetworkManager\n"
|
"# Created by NetworkManager\n"
|
||||||
"\n"
|
"\n"
|
||||||
"send dhcp-client-identifier \"1234\"; # added by NetworkManager\n"
|
"send dhcp-client-identifier \"\\x00abcd\"; # added by NetworkManager\n"
|
||||||
"\n"
|
"\n"
|
||||||
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\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 ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
|
||||||
|
|
@ -172,7 +172,36 @@ test_quote_client_id (void)
|
||||||
{
|
{
|
||||||
test_config (NULL, quote_client_id_expected,
|
test_config (NULL, quote_client_id_expected,
|
||||||
AF_INET, NULL, 0, FALSE,
|
AF_INET, NULL, 0, FALSE,
|
||||||
"1234",
|
"abcd",
|
||||||
|
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,
|
NULL,
|
||||||
"eth0",
|
"eth0",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
@ -183,7 +212,7 @@ test_quote_client_id (void)
|
||||||
static const char *ascii_client_id_expected = \
|
static const char *ascii_client_id_expected = \
|
||||||
"# Created by NetworkManager\n"
|
"# Created by NetworkManager\n"
|
||||||
"\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"
|
"\n"
|
||||||
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\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 ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
|
||||||
|
|
@ -239,13 +268,13 @@ test_hex_single_client_id (void)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static const char *existing_hex_client_id_orig = \
|
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 = \
|
static const char *existing_hex_client_id_expected = \
|
||||||
"# Created by NetworkManager\n"
|
"# Created by NetworkManager\n"
|
||||||
"# Merged from /path/to/dhclient.conf\n"
|
"# Merged from /path/to/dhclient.conf\n"
|
||||||
"\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"
|
"\n"
|
||||||
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\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 ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
|
||||||
|
|
@ -262,7 +291,7 @@ static void
|
||||||
test_existing_hex_client_id (void)
|
test_existing_hex_client_id (void)
|
||||||
{
|
{
|
||||||
gs_unref_bytes GBytes *new_client_id = NULL;
|
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));
|
new_client_id = g_bytes_new (bytes, sizeof (bytes));
|
||||||
test_config (existing_hex_client_id_orig, existing_hex_client_id_expected,
|
test_config (existing_hex_client_id_orig, existing_hex_client_id_expected,
|
||||||
|
|
@ -275,16 +304,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"
|
#define EACID "qb:cd:ef:12:34:56"
|
||||||
|
|
||||||
static const char *existing_ascii_client_id_orig = \
|
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 = \
|
static const char *existing_ascii_client_id_expected = \
|
||||||
"# Created by NetworkManager\n"
|
"# Created by NetworkManager\n"
|
||||||
"# Merged from /path/to/dhclient.conf\n"
|
"# Merged from /path/to/dhclient.conf\n"
|
||||||
"\n"
|
"\n"
|
||||||
"send dhcp-client-identifier \"" EACID "\";\n"
|
"send dhcp-client-identifier \"\\x00" EACID "\";\n"
|
||||||
"\n"
|
"\n"
|
||||||
"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\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 ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
|
||||||
|
|
@ -1036,9 +1101,11 @@ main (int argc, char **argv)
|
||||||
g_test_add_func ("/dhcp/dhclient/orig_missing", test_orig_missing);
|
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/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", test_quote_client_id);
|
||||||
|
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/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/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-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/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", test_fqdn);
|
||||||
g_test_add_func ("/dhcp/dhclient/fqdn_options_override", test_fqdn_options_override);
|
g_test_add_func ("/dhcp/dhclient/fqdn_options_override", test_fqdn_options_override);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue