shared: extend nm_utils_hexstr2bin_full() to require hexdigits in pairs

nm_utils_hexstr2bin_full() is our general hexstr to binary parsing
method. It uses (either mandatory or optional) delimiters. Before,
if delimiters are in use, it would accept individual hexdigits.
E.g. "a:b" would be accepted as "0a:0b:.

Add an argument that prevents accepting such single digits.
This commit is contained in:
Thomas Haller 2020-09-22 16:59:22 +02:00
parent 798cf37621
commit e8dd19bb01
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
8 changed files with 67 additions and 8 deletions

View file

@ -501,7 +501,7 @@ nmcs_utils_hwaddr_normalize (const char *hwaddr, gssize len)
nm_assert (hwaddr);
hwaddr = nm_strndup_a (300, hwaddr, len, &hwaddr_clone);
}
if(!nm_utils_hexstr2bin_full (hwaddr, FALSE, FALSE, ":-", sizeof (buf), buf, sizeof (buf), NULL))
if(!nm_utils_hexstr2bin_full (hwaddr, FALSE, FALSE, FALSE, ":-", sizeof (buf), buf, sizeof (buf), NULL))
return NULL;
return nm_utils_hwaddr_ntoa (buf, sizeof (buf));

View file

@ -4041,7 +4041,7 @@ nm_utils_hexstr2bin (const char *hex)
return g_bytes_new_take (buffer, len);
}
#define hwaddr_aton(asc, buffer, buffer_len, out_len) nm_utils_hexstr2bin_full ((asc), FALSE, TRUE, ":-", 0, (buffer), (buffer_len), (out_len))
#define hwaddr_aton(asc, buffer, buffer_len, out_len) nm_utils_hexstr2bin_full ((asc), FALSE, TRUE, FALSE, ":-", 0, (buffer), (buffer_len), (out_len))
/**
* nm_utils_hwaddr_atoba:
@ -5021,7 +5021,7 @@ _nm_utils_dhcp_duid_valid (const char *duid, GBytes **out_duid_bin)
return TRUE;
}
if (nm_utils_hexstr2bin_full (duid, FALSE, FALSE, ":", 0, duid_arr, sizeof (duid_arr), &duid_len)) {
if (nm_utils_hexstr2bin_full (duid, FALSE, FALSE, FALSE, ":", 0, duid_arr, sizeof (duid_arr), &duid_len)) {
/* MAX DUID length is 128 octects + the type code (2 octects). */
if ( duid_len > 2
&& duid_len <= (128 + 2)) {

View file

@ -4474,6 +4474,7 @@ guint8 *
nm_utils_hexstr2bin_full (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
gboolean hexdigit_pairs_required,
const char *delimiter_candidates,
gsize required_len,
guint8 *buffer,
@ -4517,12 +4518,14 @@ nm_utils_hexstr2bin_full (const char *hexstr,
/* Fake leading zero */
*out++ = i1;
if (!d2) {
if (!delimiter_has) {
if ( !delimiter_has
|| hexdigit_pairs_required) {
/* when using no delimiter, there must be pairs of hex chars */
goto fail;
}
break;
}
} else if (hexdigit_pairs_required)
goto fail;
in += 1;
}
@ -4598,6 +4601,7 @@ nm_utils_hexstr2bin_alloc (const char *hexstr,
if (nm_utils_hexstr2bin_full (hexstr,
FALSE,
delimiter_required,
FALSE,
delimiter_candidates,
required_len,
buffer,

View file

@ -2020,6 +2020,7 @@ char *nm_utils_bin2hexstr_full (gconstpointer addr,
guint8 *nm_utils_hexstr2bin_full (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
gboolean hexdigit_pairs_required,
const char *delimiter_candidates,
gsize required_len,
guint8 *buffer,
@ -2027,7 +2028,7 @@ guint8 *nm_utils_hexstr2bin_full (const char *hexstr,
gsize *out_len);
#define nm_utils_hexstr2bin_buf(hexstr, allow_0x_prefix, delimiter_required, delimiter_candidates, buffer) \
nm_utils_hexstr2bin_full ((hexstr), (allow_0x_prefix), (delimiter_required), (delimiter_candidates), G_N_ELEMENTS (buffer), (buffer), G_N_ELEMENTS (buffer), NULL)
nm_utils_hexstr2bin_full ((hexstr), (allow_0x_prefix), (delimiter_required), FALSE, (delimiter_candidates), G_N_ELEMENTS (buffer), (buffer), G_N_ELEMENTS (buffer), NULL)
guint8 *nm_utils_hexstr2bin_alloc (const char *hexstr,
gboolean allow_0x_prefix,

View file

@ -463,7 +463,7 @@ test_nm_utils_bin2hexstr (void)
{
int n_run;
for (n_run = 0; n_run < 100; n_run++) {
for (n_run = 0; n_run < 500; n_run++) {
guint8 buf[100];
guint8 buf2[G_N_ELEMENTS (buf) + 1];
gsize len = nmtst_get_rand_uint32 () % (G_N_ELEMENTS (buf) + 1);
@ -471,12 +471,14 @@ test_nm_utils_bin2hexstr (void)
gboolean allocate = nmtst_get_rand_bool ();
char delimiter = nmtst_get_rand_bool () ? ':' : '\0';
gboolean upper_case = nmtst_get_rand_bool ();
gboolean hexdigit_pairs_mangled;
gsize expected_strlen;
char *str_hex;
gsize required_len;
gboolean outlen_set;
gsize outlen;
guint8 *bin2;
guint i, j;
nmtst_rand_buf (NULL, buf, len);
@ -502,6 +504,38 @@ test_nm_utils_bin2hexstr (void)
? (ch >= 'A' && ch <= 'F')
: (ch >= 'a' && ch <= 'f'))));
hexdigit_pairs_mangled = FALSE;
if ( delimiter
&& len > 1
&& nmtst_get_rand_bool ()) {
/* randomly convert "0?" sequences to single digits, so we can get hexdigit_pairs_required
* parameter. */
g_assert (strlen (str_hex) >= 5);
g_assert (str_hex[2] == delimiter);
i = 0;
j = 0;
for (;;) {
g_assert (g_ascii_isxdigit (str_hex[i]));
g_assert (g_ascii_isxdigit (str_hex[i+1]));
g_assert (NM_IN_SET (str_hex[i+2], delimiter, '\0'));
if ( str_hex[i] == '0'
&& nmtst_get_rand_bool ()) {
i++;
str_hex[j++] = str_hex[i++];
hexdigit_pairs_mangled = TRUE;
} else {
str_hex[j++] = str_hex[i++];
str_hex[j++] = str_hex[i++];
}
if (str_hex[i] == '\0') {
str_hex[j] = '\0';
break;
}
g_assert (str_hex[i] == delimiter);
str_hex[j++] = str_hex[i++];
}
}
required_len = nmtst_get_rand_bool () ? len : 0u;
outlen_set = required_len == 0 || nmtst_get_rand_bool ();
@ -511,6 +545,7 @@ test_nm_utils_bin2hexstr (void)
bin2 = nm_utils_hexstr2bin_full (str_hex,
nmtst_get_rand_bool (),
delimiter != '\0' && nmtst_get_rand_bool (),
!hexdigit_pairs_mangled && nmtst_get_rand_bool (),
delimiter != '\0'
? nmtst_rand_select ((const char *) ":", ":-")
: nmtst_rand_select ((const char *) ":", ":-", "", NULL),
@ -531,6 +566,23 @@ test_nm_utils_bin2hexstr (void)
g_assert (buf2[len] == '\0');
if (hexdigit_pairs_mangled) {
/* we mangled the hexstr to contain single digits. Trying to parse with
* hexdigit_pairs_required must now fail. */
bin2 = nm_utils_hexstr2bin_full (str_hex,
nmtst_get_rand_bool (),
delimiter != '\0' && nmtst_get_rand_bool (),
TRUE,
delimiter != '\0'
? nmtst_rand_select ((const char *) ":", ":-")
: nmtst_rand_select ((const char *) ":", ":-", "", NULL),
required_len,
buf2,
len,
outlen_set ? &outlen : NULL);
g_assert (!bin2);
}
if (allocate)
g_free (str_hex);
}

View file

@ -2441,6 +2441,7 @@ again:
|| nm_utils_file_get_contents (-1, LOCALSTATEDIR"/lib/dbus/machine-id", 100*1024, 0, &content, NULL, NULL, NULL)) {
g_strstrip (content);
if (nm_utils_hexstr2bin_full (content,
FALSE,
FALSE,
FALSE,
NULL,

View file

@ -172,7 +172,7 @@ _secret_password_raw_to_bytes (const char *ifcfg_key,
password_raw += 2;
secret = nm_secret_buf_new (strlen (password_raw) / 2 + 3);
if (!nm_utils_hexstr2bin_full (password_raw, FALSE, FALSE, ":", 0, secret->bin, secret->len, &len)) {
if (!nm_utils_hexstr2bin_full (password_raw, FALSE, FALSE, FALSE, ":", 0, secret->bin, secret->len, &len)) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid hex password in %s",
ifcfg_key);

View file

@ -722,6 +722,7 @@ add_wep_key (NMSupplicantConfig *self,
guint8 buffer[26/2];
if (!nm_utils_hexstr2bin_full (key,
FALSE,
FALSE,
FALSE,
NULL,