Commit 53b747ff authored by Thomas Haller's avatar Thomas Haller

all: move nm_utils_hexstr2bin*() to shared

libnm exposes simplified variants of hexstr2bin in its public API. I
think that was a mistake, because libnm should provide NetworkManager
specific utils. It should not provide such string functions.

However, nmcli used to need this, so it was added to libnm.

The better approach is to add it to our internally shared static
library, so that all interested components can make use of it.
parent 974a010d
...@@ -249,27 +249,6 @@ guint nm_setting_ethtool_init_features (NMSettingEthtool *setting, ...@@ -249,27 +249,6 @@ guint nm_setting_ethtool_init_features (NMSettingEthtool *setting,
guint8 *_nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gsize *out_length); guint8 *_nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gsize *out_length);
const char *nm_utils_hwaddr_ntoa_buf (gconstpointer addr, gsize addr_len, gboolean upper_case, char *buf, gsize buf_len); const char *nm_utils_hwaddr_ntoa_buf (gconstpointer addr, gsize addr_len, gboolean upper_case, char *buf, gsize buf_len);
char *_nm_utils_bin2hexstr_full (gconstpointer addr, gsize length, const char delimiter, gboolean upper_case, char *out);
guint8 *_nm_utils_hexstr2bin_full (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
guint8 *buffer,
gsize buffer_len,
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)
guint8 *_nm_utils_hexstr2bin_alloc (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
gsize *out_len);
GSList * _nm_utils_hash_values_to_slist (GHashTable *hash); GSList * _nm_utils_hash_values_to_slist (GHashTable *hash);
GHashTable *_nm_utils_copy_strdict (GHashTable *strdict); GHashTable *_nm_utils_copy_strdict (GHashTable *strdict);
......
...@@ -3874,147 +3874,6 @@ nm_utils_hwaddr_len (int type) ...@@ -3874,147 +3874,6 @@ nm_utils_hwaddr_len (int type)
g_return_val_if_reached (0); g_return_val_if_reached (0);
} }
guint8 *
_nm_utils_hexstr2bin_full (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
guint8 *buffer,
gsize buffer_len,
gsize *out_len)
{
const char *in = hexstr;
guint8 *out = buffer;
gboolean delimiter_has = TRUE;
guint8 delimiter = '\0';
gsize len;
nm_assert (hexstr);
nm_assert (buffer);
nm_assert (required_len > 0 || out_len);
if ( allow_0x_prefix
&& in[0] == '0'
&& in[1] == 'x')
in += 2;
while (TRUE) {
const guint8 d1 = in[0];
guint8 d2;
int i1, i2;
i1 = nm_utils_hexchar_to_int (d1);
if (i1 < 0)
goto fail;
/* If there's no leading zero (ie "aa:b:cc") then fake it */
d2 = in[1];
if ( d2
&& (i2 = nm_utils_hexchar_to_int (d2)) >= 0) {
*out++ = (i1 << 4) + i2;
d2 = in[2];
if (!d2)
break;
in += 2;
} else {
/* Fake leading zero */
*out++ = i1;
if (!d2) {
if (!delimiter_has) {
/* when using no delimiter, there must be pairs of hex chars */
goto fail;
}
break;
}
in += 1;
}
if (--buffer_len == 0)
goto fail;
if (delimiter_has) {
if (d2 != delimiter) {
if (delimiter)
goto fail;
if (delimiter_candidates) {
while (delimiter_candidates[0]) {
if (delimiter_candidates++[0] == d2)
delimiter = d2;
}
}
if (!delimiter) {
if (delimiter_required)
goto fail;
delimiter_has = FALSE;
continue;
}
}
in++;
}
}
len = out - buffer;
if ( required_len == 0
|| len == required_len) {
NM_SET_OUT (out_len, len);
return buffer;
}
fail:
NM_SET_OUT (out_len, 0);
return NULL;
}
guint8 *
_nm_utils_hexstr2bin_alloc (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
gsize *out_len)
{
guint8 *buffer;
gsize buffer_len, len;
g_return_val_if_fail (hexstr, NULL);
nm_assert (required_len > 0 || out_len);
if ( allow_0x_prefix
&& hexstr[0] == '0'
&& hexstr[1] == 'x')
hexstr += 2;
if (!hexstr[0])
goto fail;
if (required_len > 0)
buffer_len = required_len;
else
buffer_len = strlen (hexstr) / 2 + 3;
buffer = g_malloc (buffer_len);
if (_nm_utils_hexstr2bin_full (hexstr,
FALSE,
delimiter_required,
delimiter_candidates,
required_len,
buffer,
buffer_len,
&len)) {
NM_SET_OUT (out_len, len);
return buffer;
}
g_free (buffer);
fail:
NM_SET_OUT (out_len, 0);
return NULL;
}
/** /**
* nm_utils_hexstr2bin: * nm_utils_hexstr2bin:
* @hex: a string of hexadecimal characters with optional ':' separators * @hex: a string of hexadecimal characters with optional ':' separators
...@@ -4032,14 +3891,14 @@ nm_utils_hexstr2bin (const char *hex) ...@@ -4032,14 +3891,14 @@ nm_utils_hexstr2bin (const char *hex)
guint8 *buffer; guint8 *buffer;
gsize len; gsize len;
buffer = _nm_utils_hexstr2bin_alloc (hex, TRUE, FALSE, ":", 0, &len); buffer = nm_utils_hexstr2bin_alloc (hex, TRUE, FALSE, ":", 0, &len);
if (!buffer) if (!buffer)
return NULL; return NULL;
buffer = g_realloc (buffer, len); buffer = g_realloc (buffer, len);
return g_bytes_new_take (buffer, len); 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, ":-", 0, (buffer), (buffer_len), (out_len))
/** /**
* nm_utils_hwaddr_atoba: * nm_utils_hwaddr_atoba:
...@@ -4976,7 +4835,7 @@ _nm_utils_dhcp_duid_valid (const char *duid, GBytes **out_duid_bin) ...@@ -4976,7 +4835,7 @@ _nm_utils_dhcp_duid_valid (const char *duid, GBytes **out_duid_bin)
return TRUE; 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, ":", 0, duid_arr, sizeof (duid_arr), &duid_len)) {
/* MAX DUID length is 128 octects + the type code (2 octects). */ /* MAX DUID length is 128 octects + the type code (2 octects). */
if ( duid_len > 2 if ( duid_len > 2
&& duid_len <= (128 + 2)) { && duid_len <= (128 + 2)) {
......
...@@ -2594,3 +2594,144 @@ nm_utils_bin2hexstr_full (gconstpointer addr, ...@@ -2594,3 +2594,144 @@ nm_utils_bin2hexstr_full (gconstpointer addr,
*out = 0; *out = 0;
return out0; return out0;
} }
guint8 *
nm_utils_hexstr2bin_full (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
guint8 *buffer,
gsize buffer_len,
gsize *out_len)
{
const char *in = hexstr;
guint8 *out = buffer;
gboolean delimiter_has = TRUE;
guint8 delimiter = '\0';
gsize len;
nm_assert (hexstr);
nm_assert (buffer);
nm_assert (required_len > 0 || out_len);
if ( allow_0x_prefix
&& in[0] == '0'
&& in[1] == 'x')
in += 2;
while (TRUE) {
const guint8 d1 = in[0];
guint8 d2;
int i1, i2;
i1 = nm_utils_hexchar_to_int (d1);
if (i1 < 0)
goto fail;
/* If there's no leading zero (ie "aa:b:cc") then fake it */
d2 = in[1];
if ( d2
&& (i2 = nm_utils_hexchar_to_int (d2)) >= 0) {
*out++ = (i1 << 4) + i2;
d2 = in[2];
if (!d2)
break;
in += 2;
} else {
/* Fake leading zero */
*out++ = i1;
if (!d2) {
if (!delimiter_has) {
/* when using no delimiter, there must be pairs of hex chars */
goto fail;
}
break;
}
in += 1;
}
if (--buffer_len == 0)
goto fail;
if (delimiter_has) {
if (d2 != delimiter) {
if (delimiter)
goto fail;
if (delimiter_candidates) {
while (delimiter_candidates[0]) {
if (delimiter_candidates++[0] == d2)
delimiter = d2;
}
}
if (!delimiter) {
if (delimiter_required)
goto fail;
delimiter_has = FALSE;
continue;
}
}
in++;
}
}
len = out - buffer;
if ( required_len == 0
|| len == required_len) {
NM_SET_OUT (out_len, len);
return buffer;
}
fail:
NM_SET_OUT (out_len, 0);
return NULL;
}
guint8 *
nm_utils_hexstr2bin_alloc (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
gsize *out_len)
{
guint8 *buffer;
gsize buffer_len, len;
g_return_val_if_fail (hexstr, NULL);
nm_assert (required_len > 0 || out_len);
if ( allow_0x_prefix
&& hexstr[0] == '0'
&& hexstr[1] == 'x')
hexstr += 2;
if (!hexstr[0])
goto fail;
if (required_len > 0)
buffer_len = required_len;
else
buffer_len = strlen (hexstr) / 2 + 3;
buffer = g_malloc (buffer_len);
if (nm_utils_hexstr2bin_full (hexstr,
FALSE,
delimiter_required,
delimiter_candidates,
required_len,
buffer,
buffer_len,
&len)) {
NM_SET_OUT (out_len, len);
return buffer;
}
g_free (buffer);
fail:
NM_SET_OUT (out_len, 0);
return NULL;
}
...@@ -1128,10 +1128,31 @@ nm_strv_ptrarray_take_gstring (GPtrArray *cmd, ...@@ -1128,10 +1128,31 @@ nm_strv_ptrarray_take_gstring (GPtrArray *cmd,
int nm_utils_getpagesize (void); int nm_utils_getpagesize (void);
/*****************************************************************************/
char *nm_utils_bin2hexstr_full (gconstpointer addr, char *nm_utils_bin2hexstr_full (gconstpointer addr,
gsize length, gsize length,
char delimiter, char delimiter,
gboolean upper_case, gboolean upper_case,
char *out); char *out);
guint8 *nm_utils_hexstr2bin_full (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
guint8 *buffer,
gsize buffer_len,
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)
guint8 *nm_utils_hexstr2bin_alloc (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
gsize *out_len);
#endif /* __NM_SHARED_UTILS_H__ */ #endif /* __NM_SHARED_UTILS_H__ */
...@@ -2428,14 +2428,14 @@ again: ...@@ -2428,14 +2428,14 @@ again:
if ( nm_utils_file_get_contents (-1, "/etc/machine-id", 100*1024, 0, &content, NULL, NULL) >= 0 if ( nm_utils_file_get_contents (-1, "/etc/machine-id", 100*1024, 0, &content, NULL, NULL) >= 0
|| nm_utils_file_get_contents (-1, LOCALSTATEDIR"/lib/dbus/machine-id", 100*1024, 0, &content, NULL, NULL) >= 0) { || nm_utils_file_get_contents (-1, LOCALSTATEDIR"/lib/dbus/machine-id", 100*1024, 0, &content, NULL, NULL) >= 0) {
g_strstrip (content); g_strstrip (content);
if (_nm_utils_hexstr2bin_full (content, if (nm_utils_hexstr2bin_full (content,
FALSE, FALSE,
FALSE, FALSE,
NULL, NULL,
16, 16,
(guint8 *) &uuid, (guint8 *) &uuid,
sizeof (uuid), sizeof (uuid),
NULL)) { NULL)) {
if (!nm_utils_uuid_is_null (&uuid)) { if (!nm_utils_uuid_is_null (&uuid)) {
/* an all-zero machine-id is not valid. */ /* an all-zero machine-id is not valid. */
is_fake = FALSE; is_fake = FALSE;
......
...@@ -187,7 +187,7 @@ _secret_password_raw_to_bytes (const char *ifcfg_key, ...@@ -187,7 +187,7 @@ _secret_password_raw_to_bytes (const char *ifcfg_key,
password_raw += 2; password_raw += 2;
secret = nm_secret_buf_new (strlen (password_raw) / 2 + 3); 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, ":", 0, secret->bin, secret->len, &len)) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid hex password in %s", "Invalid hex password in %s",
ifcfg_key); ifcfg_key);
......
...@@ -403,11 +403,11 @@ nm_supplicant_config_add_setting_macsec (NMSupplicantConfig * self, ...@@ -403,11 +403,11 @@ nm_supplicant_config_add_setting_macsec (NMSupplicantConfig * self,
value = nm_setting_macsec_get_mka_cak (setting); value = nm_setting_macsec_get_mka_cak (setting);
if ( !value if ( !value
|| !_nm_utils_hexstr2bin_buf (value, || !nm_utils_hexstr2bin_buf (value,
FALSE, FALSE,
FALSE, FALSE,
NULL, NULL,
buffer_cak)) { buffer_cak)) {
g_set_error_literal (error, g_set_error_literal (error,
NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR,
NM_SUPPLICANT_ERROR_CONFIG, NM_SUPPLICANT_ERROR_CONFIG,
...@@ -424,11 +424,11 @@ nm_supplicant_config_add_setting_macsec (NMSupplicantConfig * self, ...@@ -424,11 +424,11 @@ nm_supplicant_config_add_setting_macsec (NMSupplicantConfig * self,
value = nm_setting_macsec_get_mka_ckn (setting); value = nm_setting_macsec_get_mka_ckn (setting);
if ( !value if ( !value
|| !_nm_utils_hexstr2bin_buf (value, || !nm_utils_hexstr2bin_buf (value,
FALSE, FALSE,
FALSE, FALSE,
NULL, NULL,
buffer_ckn)) { buffer_ckn)) {
g_set_error_literal (error, g_set_error_literal (error,
NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR,
NM_SUPPLICANT_ERROR_CONFIG, NM_SUPPLICANT_ERROR_CONFIG,
...@@ -704,14 +704,14 @@ add_wep_key (NMSupplicantConfig *self, ...@@ -704,14 +704,14 @@ add_wep_key (NMSupplicantConfig *self,
if ((key_len == 10) || (key_len == 26)) { if ((key_len == 10) || (key_len == 26)) {
guint8 buffer[26/2]; guint8 buffer[26/2];
if (!_nm_utils_hexstr2bin_full (key, if (!nm_utils_hexstr2bin_full (key,
FALSE, FALSE,
FALSE, FALSE,
NULL, NULL,
key_len / 2, key_len / 2,
buffer, buffer,
sizeof (buffer), sizeof (buffer),
NULL)) { NULL)) {
g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
"cannot add wep-key %s to suplicant config because key is not hex", "cannot add wep-key %s to suplicant config because key is not hex",
name); name);
...@@ -825,11 +825,11 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, ...@@ -825,11 +825,11 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
guint8 buffer[32]; guint8 buffer[32];
/* Hex PSK */ /* Hex PSK */
if (!_nm_utils_hexstr2bin_buf (psk, if (!nm_utils_hexstr2bin_buf (psk,
FALSE, FALSE,
FALSE, FALSE,
NULL, NULL,
buffer)) { buffer)) {
g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
"Cannot add psk to supplicant config due to invalid hex"); "Cannot add psk to supplicant config due to invalid hex");
return FALSE; return FALSE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment