diff options
Diffstat (limited to 'libnm-core/nm-utils.c')
| -rw-r--r-- | libnm-core/nm-utils.c | 757 |
1 files changed, 348 insertions, 409 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index f6e1555e..b700c7f5 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -43,7 +43,7 @@ #include "nm-common-macros.h" #include "nm-utils-private.h" #include "nm-setting-private.h" -#include "nm-crypto.h" +#include "crypto.h" #include "nm-setting-bond.h" #include "nm-setting-bridge.h" #include "nm-setting-infiniband.h" @@ -230,33 +230,31 @@ get_system_encodings (void) return cached_encodings; } -/*****************************************************************************/ +/* init libnm */ + +static gboolean initialized = FALSE; static void __attribute__((constructor)) _nm_utils_init (void) { - static int initialized = 0; + GModule *self; + gpointer func; - if (g_atomic_int_get (&initialized) != 0) + if (initialized) return; + initialized = TRUE; - /* we don't expect this code to run multiple times, nor on multiple threads. - * - * In practice, it would not be a problem if two threads concurrently try to - * run the initialization code below, all code below itself is thread-safe, - * Hence, a poor-man guard "initialized" above is more than sufficient, - * although it does not guarantee that the code is not run concurrently. */ + self = g_module_open (NULL, 0); + if (g_module_symbol (self, "nm_util_get_private", &func)) + g_error ("libnm-util symbols detected; Mixing libnm with libnm-util/libnm-glib is not supported"); + g_module_close (self); bindtextdomain (GETTEXT_PACKAGE, NMLOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); _nm_dbus_errors_init (); - - g_atomic_int_set (&initialized, 1); } -/*****************************************************************************/ - gboolean _nm_utils_is_manager_process; /* ssid helpers */ @@ -302,19 +300,19 @@ nm_utils_ssid_to_utf8 (const guint8 *ssid, gsize len) g_return_val_if_fail (ssid != NULL, NULL); - if (g_utf8_validate ((const char *) ssid, len, NULL)) - return g_strndup ((const char *) ssid, len); + if (g_utf8_validate ((const gchar *) ssid, len, NULL)) + return g_strndup ((const gchar *) ssid, len); encodings = get_system_encodings (); for (e = encodings; *e; e++) { - converted = g_convert ((const char *) ssid, len, "UTF-8", *e, NULL, NULL, NULL); + converted = g_convert ((const gchar *) ssid, len, "UTF-8", *e, NULL, NULL, NULL); if (converted) break; } if (!converted) { - converted = g_convert_with_fallback ((const char *) ssid, len, + converted = g_convert_with_fallback ((const gchar *) ssid, len, "UTF-8", encodings[0], "?", NULL, NULL, NULL); } @@ -325,7 +323,7 @@ nm_utils_ssid_to_utf8 (const guint8 *ssid, gsize len) */ /* Use the printable range of 0x20-0x7E */ - char *valid_chars = " !\"#$%&'()*+,-./0123456789:;<=>?@" + gchar *valid_chars = " !\"#$%&'()*+,-./0123456789:;<=>?@" "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" "abcdefghijklmnopqrstuvwxyz{|}~"; @@ -336,18 +334,6 @@ nm_utils_ssid_to_utf8 (const guint8 *ssid, gsize len) return converted; } -char * -_nm_utils_ssid_to_utf8 (GBytes *ssid) -{ - const guint8 *p; - gsize l; - - g_return_val_if_fail (ssid, NULL); - - p = g_bytes_get_data (ssid, &l); - return nm_utils_ssid_to_utf8 (p, l); -} - /* Shamelessly ripped from the Linux kernel ieee80211 stack */ /** * nm_utils_is_empty_ssid: @@ -375,18 +361,6 @@ nm_utils_is_empty_ssid (const guint8 *ssid, gsize len) return TRUE; } -gboolean -_nm_utils_is_empty_ssid (GBytes *ssid) -{ - const guint8 *p; - gsize l; - - g_return_val_if_fail (ssid, FALSE); - - p = g_bytes_get_data (ssid, &l); - return nm_utils_is_empty_ssid (p, l); -} - #define ESSID_MAX_SIZE 32 /** @@ -428,37 +402,6 @@ nm_utils_escape_ssid (const guint8 *ssid, gsize len) return escaped; } -char * -_nm_utils_ssid_to_string_arr (const guint8 *ssid, gsize len) -{ - gs_free char *s_copy = NULL; - const char *s_cnst; - - if (len == 0) - return g_strdup ("(empty)"); - - s_cnst = nm_utils_buf_utf8safe_escape (ssid, len, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, &s_copy); - nm_assert (s_cnst); - - if (nm_utils_is_empty_ssid (ssid, len)) - return g_strdup_printf ("\"%s\" (hidden)", s_cnst); - - return g_strdup_printf ("\"%s\"", s_cnst); -} - -char * -_nm_utils_ssid_to_string (GBytes *ssid) -{ - gconstpointer p; - gsize l; - - if (!ssid) - return g_strdup ("(none)"); - - p = g_bytes_get_data (ssid, &l); - return _nm_utils_ssid_to_string_arr (p, l); -} - /** * nm_utils_same_ssid: * @ssid1: (array length=len1): the first SSID to compare @@ -623,6 +566,39 @@ _nm_utils_copy_strdict (GHashTable *strdict) } GPtrArray * +_nm_utils_copy_slist_to_array (const GSList *list, + NMUtilsCopyFunc copy_func, + GDestroyNotify unref_func) +{ + const GSList *iter; + GPtrArray *array; + + array = g_ptr_array_new_with_free_func (unref_func); + for (iter = list; iter; iter = iter->next) + g_ptr_array_add (array, copy_func ? copy_func (iter->data) : iter->data); + return array; +} + +GSList * +_nm_utils_copy_array_to_slist (const GPtrArray *array, + NMUtilsCopyFunc copy_func) +{ + GSList *slist = NULL; + gpointer item; + int i; + + if (!array) + return NULL; + + for (i = 0; i < array->len; i++) { + item = array->pdata[i]; + slist = g_slist_prepend (slist, copy_func (item)); + } + + return g_slist_reverse (slist); +} + +GPtrArray * _nm_utils_copy_array (const GPtrArray *array, NMUtilsCopyFunc copy_func, GDestroyNotify free_func) @@ -669,6 +645,136 @@ _nm_utils_ptrarray_find_first (gconstpointer *list, gssize len, gconstpointer ne return -1; } +gssize +_nm_utils_ptrarray_find_binary_search (gconstpointer *list, + gsize len, + gconstpointer needle, + GCompareDataFunc cmpfcn, + gpointer user_data, + gssize *out_idx_first, + gssize *out_idx_last) +{ + gssize imin, imax, imid, i2min, i2max, i2mid; + int cmp; + + g_return_val_if_fail (list || !len, ~((gssize) 0)); + g_return_val_if_fail (cmpfcn, ~((gssize) 0)); + + imin = 0; + if (len > 0) { + imax = len - 1; + + while (imin <= imax) { + imid = imin + (imax - imin) / 2; + + cmp = cmpfcn (list[imid], needle, user_data); + if (cmp == 0) { + /* we found a matching entry at index imid. + * + * Does the caller request the first/last index as well (in case that + * there are multiple entries which compare equal). */ + + if (out_idx_first) { + i2min = imin; + i2max = imid + 1; + while (i2min <= i2max) { + i2mid = i2min + (i2max - i2min) / 2; + + cmp = cmpfcn (list[i2mid], needle, user_data); + if (cmp == 0) + i2max = i2mid -1; + else { + nm_assert (cmp < 0); + i2min = i2mid + 1; + } + } + *out_idx_first = i2min; + } + if (out_idx_last) { + i2min = imid + 1; + i2max = imax; + while (i2min <= i2max) { + i2mid = i2min + (i2max - i2min) / 2; + + cmp = cmpfcn (list[i2mid], needle, user_data); + if (cmp == 0) + i2min = i2mid + 1; + else { + nm_assert (cmp > 0); + i2max = i2mid - 1; + } + } + *out_idx_last = i2min - 1; + } + return imid; + } + + if (cmp < 0) + imin = imid + 1; + else + imax = imid - 1; + } + } + + /* return the inverse of @imin. This is a negative number, but + * also is ~imin the position where the value should be inserted. */ + imin = ~imin; + NM_SET_OUT (out_idx_first, imin); + NM_SET_OUT (out_idx_last, imin); + return imin; +} + +gssize +_nm_utils_array_find_binary_search (gconstpointer list, gsize elem_size, gsize len, gconstpointer needle, GCompareDataFunc cmpfcn, gpointer user_data) +{ + gssize imin, imax, imid; + int cmp; + + g_return_val_if_fail (list || !len, ~((gssize) 0)); + g_return_val_if_fail (cmpfcn, ~((gssize) 0)); + g_return_val_if_fail (elem_size > 0, ~((gssize) 0)); + + imin = 0; + if (len == 0) + return ~imin; + + imax = len - 1; + + while (imin <= imax) { + imid = imin + (imax - imin) / 2; + + cmp = cmpfcn (&((const char *) list)[elem_size * imid], needle, user_data); + if (cmp == 0) + return imid; + + if (cmp < 0) + imin = imid + 1; + else + imax = imid - 1; + } + + /* return the inverse of @imin. This is a negative number, but + * also is ~imin the position where the value should be inserted. */ + return ~imin; +} + +GVariant * +_nm_utils_bytes_to_dbus (const GValue *prop_value) +{ + GBytes *bytes = g_value_get_boxed (prop_value); + + if (bytes) { + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), + 1); + } else { + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + NULL, 0, + 1); + } +} + void _nm_utils_bytes_from_dbus (GVariant *dbus_value, GValue *prop_value) @@ -2141,10 +2247,10 @@ _tc_read_common_opts (const char *str, gs_unref_hashtable GHashTable *ht = NULL; GVariant *variant; - ht = nm_utils_parse_variant_attributes (str, - ' ', ' ', FALSE, - tc_object_attribute_spec, - error); + ht = nm_utils_parse_variant_attributes (str, + ' ', ' ', FALSE, + tc_object_attribute_spec, + error); if (!ht) return FALSE; @@ -2504,10 +2610,10 @@ nm_utils_tc_tfilter_from_str (const char *str, GError **error) return NULL; if (rest) { - ht = nm_utils_parse_variant_attributes (rest, - ' ', ' ', FALSE, - tc_tfilter_attribute_spec, - error); + ht = nm_utils_parse_variant_attributes (rest, + ' ', ' ', FALSE, + tc_tfilter_attribute_spec, + error); if (!ht) return NULL; @@ -2542,249 +2648,6 @@ nm_utils_tc_tfilter_from_str (const char *str, GError **error) /*****************************************************************************/ -extern const NMVariantAttributeSpec *const _nm_sriov_vf_attribute_spec[]; - -/** - * nm_utils_sriov_vf_to_str: - * @vf: the %NMSriovVF - * @omit_index: if %TRUE, the VF index will be omitted from output string - * @error: (out) (allow-none): location to store the error on failure - * - * Converts a SR-IOV virtual function object to its string representation. - * - * Returns: a newly allocated string or %NULL on error - * - * Since: 1.14 - */ -char * -nm_utils_sriov_vf_to_str (const NMSriovVF *vf, gboolean omit_index, GError **error) -{ - gs_free NMUtilsNamedValue *values = NULL; - gs_free const char **names = NULL; - const guint *vlan_ids; - guint num_vlans, num_attrs; - guint i; - GString *str; - - str = g_string_new (""); - if (!omit_index) - g_string_append_printf (str, "%u", nm_sriov_vf_get_index (vf)); - - names = nm_sriov_vf_get_attribute_names (vf); - num_attrs = names ? g_strv_length ((char **) names) : 0; - values = g_new0 (NMUtilsNamedValue, num_attrs); - - for (i = 0; i < num_attrs; i++) { - values[i].name = names[i]; - values[i].value_ptr = nm_sriov_vf_get_attribute (vf, names[i]); - } - - if (num_attrs > 0) { - if (!omit_index) - g_string_append_c (str, ' '); - _nm_utils_format_variant_attributes_full (str, values, num_attrs, ' ', '='); - } - - vlan_ids = nm_sriov_vf_get_vlan_ids (vf, &num_vlans); - if (num_vlans != 0) { - g_string_append (str, " vlans"); - for (i = 0; i < num_vlans; i++) { - guint32 qos; - NMSriovVFVlanProtocol protocol; - - qos = nm_sriov_vf_get_vlan_qos (vf, vlan_ids[i]); - protocol = nm_sriov_vf_get_vlan_protocol (vf, vlan_ids[i]); - - g_string_append_c (str, i == 0 ? '=' : ';'); - - g_string_append_printf (str, "%u", vlan_ids[i]); - - if ( qos != 0 - || protocol != NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q) { - g_string_append_printf (str, - ".%u%s", - (unsigned) qos, - protocol == NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q ? "" : ".ad"); - } - } - } - - return g_string_free (str, FALSE); -} - -gboolean -_nm_sriov_vf_parse_vlans (NMSriovVF *vf, const char *str, GError **error) -{ - gs_free const char **vlans = NULL; - guint i; - - vlans = nm_utils_strsplit_set (str, ";", FALSE); - if (!vlans) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_FAILED, - "empty VF VLAN"); - return FALSE; - } - - for (i = 0; vlans[i]; i++) { - gs_strfreev char **params = NULL; - guint id = G_MAXUINT; - gint64 qos = -1; - - /* we accept leading/trailing whitespace around vlans[1]. Hence - * the nm_str_skip_leading_spaces() and g_strchomp() below. - * - * However, we don't accept any whitespace inside the specifier. - * Hence the NM_STRCHAR_ALL() checks. */ - - params = g_strsplit (nm_str_skip_leading_spaces (vlans[i]), ".", 3); - if (!params || !params[0] || *params[0] == '\0') { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_FAILED, - "empty VF VLAN"); - return FALSE; - } - - if (!params[1]) - g_strchomp (params[0]); - if (NM_STRCHAR_ALL (params[0], ch, ch == 'x' || g_ascii_isdigit (ch))) - id = _nm_utils_ascii_str_to_int64 (params[0], 0, 0, 4095, G_MAXUINT); - if (id == G_MAXUINT) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_FAILED, - "invalid VF VLAN id '%s'", - params[0]); - return FALSE; - } - if (!nm_sriov_vf_add_vlan (vf, id)) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_FAILED, - "duplicate VLAN id %u", - id); - return FALSE; - } - - if (!params[1]) - continue; - - if (!params[2]) - g_strchomp (params[1]); - if (NM_STRCHAR_ALL (params[1], ch, ch == 'x' || g_ascii_isdigit (ch))) - qos = _nm_utils_ascii_str_to_int64 (params[1], 0, 0, G_MAXUINT32, -1); - if (qos == -1) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_FAILED, - "invalid VF VLAN QoS '%s'", - params[1]); - return FALSE; - } - nm_sriov_vf_set_vlan_qos (vf, id, qos); - - if (!params[2]) - continue; - - g_strchomp (params[2]); - - if (nm_streq (params[2], "ad")) - nm_sriov_vf_set_vlan_protocol (vf, id, NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD); - else if (nm_streq (params[2], "q")) - nm_sriov_vf_set_vlan_protocol (vf, id, NM_SRIOV_VF_VLAN_PROTOCOL_802_1Q); - else { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_FAILED, - "invalid VF VLAN protocol '%s'", - params[2]); - return FALSE; - } - } - - return TRUE; -} - -/** - * nm_utils_sriov_vf_from_str: - * @str: the input string - * @error: (out) (allow-none): location to store the error on failure - * - * Converts a string to a SR-IOV virtual function object. - * - * Returns: (transfer full): the virtual function object - * - * Since: 1.14 - */ -NMSriovVF * -nm_utils_sriov_vf_from_str (const char *str, GError **error) -{ - gs_free char *index_free = NULL; - const char *detail; - - g_return_val_if_fail (str, NULL); - g_return_val_if_fail (!error || !*error, NULL); - - while (*str == ' ') - str++; - - detail = strchr (str, ' '); - if (detail) { - index_free = g_strndup (str, detail - str); - str = index_free; - detail++; - } - - return _nm_utils_sriov_vf_from_strparts (str, detail, error); -} - -NMSriovVF * -_nm_utils_sriov_vf_from_strparts (const char *index, const char *detail, GError **error) -{ - NMSriovVF *vf; - guint32 n_index; - GHashTableIter iter; - char *key; - GVariant *variant; - gs_unref_hashtable GHashTable *ht = NULL; - - n_index = _nm_utils_ascii_str_to_int64 (index, 10, 0, G_MAXUINT32, 0); - if (errno) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_FAILED, - "invalid index"); - return NULL; - } - - vf = nm_sriov_vf_new (n_index); - if (detail) { - ht = nm_utils_parse_variant_attributes (detail, ' ', '=', TRUE, _nm_sriov_vf_attribute_spec, error); - if (!ht) { - nm_sriov_vf_unref (vf); - return NULL; - } - - if ((variant = g_hash_table_lookup (ht, "vlans"))) { - if (!_nm_sriov_vf_parse_vlans (vf, g_variant_get_string (variant, NULL), error)) { - nm_sriov_vf_unref (vf); - return NULL; - } - g_hash_table_remove (ht, "vlans"); - } - - g_hash_table_iter_init (&iter, ht); - while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &variant)) - nm_sriov_vf_set_attribute (vf, key, g_variant_ref_sink (variant)); - } - - return vf; -} - -/*****************************************************************************/ - /** * nm_utils_uuid_generate_buf_: * @buf: input buffer, must contain at least 37 bytes @@ -2838,17 +2701,9 @@ nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, g g_return_val_if_fail (uuid_type == NM_UTILS_UUID_TYPE_LEGACY || uuid_type == NM_UTILS_UUID_TYPE_VARIANT3, NULL); g_return_val_if_fail (!type_args || uuid_type == NM_UTILS_UUID_TYPE_VARIANT3, NULL); - if (slen < 0) - slen = s ? strlen (s) : 0; - switch (uuid_type) { case NM_UTILS_UUID_TYPE_LEGACY: - nm_crypto_md5_hash (NULL, - 0, - (guint8 *) s, - slen, - (guint8 *) uuid, - sizeof (uuid)); + crypto_md5_hash (NULL, 0, s, slen, (char *) uuid, sizeof (uuid)); break; case NM_UTILS_UUID_TYPE_VARIANT3: { uuid_t ns_uuid = { 0 }; @@ -2859,12 +2714,7 @@ nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, g g_return_val_if_reached (NULL); } - nm_crypto_md5_hash ((guint8 *) s, - slen, - (guint8 *) ns_uuid, - sizeof (ns_uuid), - (guint8 *) uuid, - sizeof (uuid)); + crypto_md5_hash (s, slen, (char *) ns_uuid, sizeof (ns_uuid), (char *) uuid, sizeof (uuid)); uuid[6] = (uuid[6] & 0x0F) | 0x30; uuid[8] = (uuid[8] & 0x3F) | 0x80; @@ -2924,6 +2774,110 @@ _nm_utils_uuid_generate_from_strings (const char *string1, ...) /*****************************************************************************/ +/** + * nm_utils_rsa_key_encrypt: + * @data: (array length=len): RSA private key data to be encrypted + * @len: length of @data + * @in_password: (allow-none): existing password to use, if any + * @out_password: (out) (allow-none): if @in_password was %NULL, a random + * password will be generated and returned in this argument + * @error: detailed error information on return, if an error occurred + * + * Encrypts the given RSA private key data with the given password (or generates + * a password if no password was given) and converts the data to PEM format + * suitable for writing to a file. It uses Triple DES cipher for the encryption. + * + * Returns: (transfer full): on success, PEM-formatted data suitable for writing + * to a PEM-formatted certificate/private key file. + **/ +GByteArray * +nm_utils_rsa_key_encrypt (const guint8 *data, + gsize len, + const char *in_password, + char **out_password, + GError **error) +{ + char salt[16]; + int salt_len; + char *key = NULL, *enc = NULL, *pw_buf[32]; + gsize key_len = 0, enc_len = 0; + GString *pem = NULL; + char *tmp, *tmp_password = NULL; + int left; + const char *p; + GByteArray *ret = NULL; + + g_return_val_if_fail (data != NULL, NULL); + g_return_val_if_fail (len > 0, NULL); + if (out_password) + g_return_val_if_fail (*out_password == NULL, NULL); + + /* Make the password if needed */ + if (!in_password) { + if (!crypto_randomize (pw_buf, sizeof (pw_buf), error)) + return NULL; + in_password = tmp_password = nm_utils_bin2hexstr (pw_buf, sizeof (pw_buf), -1); + } + + salt_len = 8; + if (!crypto_randomize (salt, salt_len, error)) + goto out; + + key = crypto_make_des_aes_key (CIPHER_DES_EDE3_CBC, &salt[0], salt_len, in_password, &key_len, NULL); + if (!key) + g_return_val_if_reached (NULL); + + enc = crypto_encrypt (CIPHER_DES_EDE3_CBC, data, len, salt, salt_len, key, key_len, &enc_len, error); + if (!enc) + goto out; + + pem = g_string_sized_new (enc_len * 2 + 100); + g_string_append (pem, "-----BEGIN RSA PRIVATE KEY-----\n"); + g_string_append (pem, "Proc-Type: 4,ENCRYPTED\n"); + + /* Convert the salt to a hex string */ + tmp = nm_utils_bin2hexstr (salt, salt_len, salt_len * 2); + g_string_append_printf (pem, "DEK-Info: %s,%s\n\n", CIPHER_DES_EDE3_CBC, tmp); + g_free (tmp); + + /* Convert the encrypted key to a base64 string */ + p = tmp = g_base64_encode ((const guchar *) enc, enc_len); + left = strlen (tmp); + while (left > 0) { + g_string_append_len (pem, p, (left < 64) ? left : 64); + g_string_append_c (pem, '\n'); + left -= 64; + p += 64; + } + g_free (tmp); + + g_string_append (pem, "-----END RSA PRIVATE KEY-----\n"); + + ret = g_byte_array_sized_new (pem->len); + g_byte_array_append (ret, (const unsigned char *) pem->str, pem->len); + if (tmp_password && out_password) + *out_password = g_strdup (tmp_password); + +out: + if (key) { + memset (key, 0, key_len); + g_free (key); + } + if (enc) { + memset (enc, 0, enc_len); + g_free (enc); + } + if (pem) + g_string_free (pem, TRUE); + + if (tmp_password) { + memset (tmp_password, 0, strlen (tmp_password)); + g_free (tmp_password); + } + + return ret; +} + static gboolean file_has_extension (const char *filename, const char *extensions[]) { @@ -2956,15 +2910,18 @@ gboolean nm_utils_file_is_certificate (const char *filename) { const char *extensions[] = { ".der", ".pem", ".crt", ".cer", NULL }; - NMCryptoFileFormat file_format; + NMCryptoFileFormat file_format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GByteArray *cert; g_return_val_if_fail (filename != NULL, FALSE); if (!file_has_extension (filename, extensions)) return FALSE; - if (!nm_crypto_load_and_verify_certificate (filename, &file_format, NULL, NULL)) - return FALSE; + cert = crypto_load_and_verify_certificate (filename, &file_format, NULL); + if (cert) + g_byte_array_unref (cert); + return file_format = NM_CRYPTO_FILE_FORMAT_X509; } @@ -2990,7 +2947,7 @@ nm_utils_file_is_private_key (const char *filename, gboolean *out_encrypted) if (!file_has_extension (filename, extensions)) return FALSE; - return nm_crypto_verify_private_key (filename, NULL, out_encrypted, NULL) != NM_CRYPTO_FILE_FORMAT_UNKNOWN; + return crypto_verify_private_key (filename, NULL, out_encrypted, NULL) != NM_CRYPTO_FILE_FORMAT_UNKNOWN; } /** @@ -3006,7 +2963,7 @@ nm_utils_file_is_pkcs12 (const char *filename) { g_return_val_if_fail (filename != NULL, FALSE); - return nm_crypto_is_pkcs12_file (filename, NULL); + return crypto_is_pkcs12_file (filename, NULL); } /*****************************************************************************/ @@ -3526,13 +3483,13 @@ nm_utils_hwaddr_len (int type) g_return_val_if_reached (0); } -guint8 * -_nm_utils_str2bin_full (const char *asc, - gboolean delimiter_required, - const char *delimiter_candidates, - guint8 *buffer, - gsize buffer_length, - gsize *out_len) +static guint8 * +_str2bin (const char *asc, + gboolean delimiter_required, + const char *delimiter_candidates, + guint8 *buffer, + gsize buffer_length, + gsize *out_len) { const char *in = asc; guint8 *out = buffer; @@ -3602,7 +3559,7 @@ _nm_utils_str2bin_full (const char *asc, return buffer; } -#define hwaddr_aton(asc, buffer, buffer_length, out_len) _nm_utils_str2bin_full ((asc), TRUE, ":-", (buffer), (buffer_length), (out_len)) +#define hwaddr_aton(asc, buffer, buffer_length, out_len) _str2bin ((asc), TRUE, ":-", (buffer), (buffer_length), (out_len)) /** * nm_utils_hexstr2bin: @@ -3628,7 +3585,7 @@ nm_utils_hexstr2bin (const char *hex) buffer_length = strlen (hex) / 2 + 3; buffer = g_malloc (buffer_length); - if (!_nm_utils_str2bin_full (hex, FALSE, ":", buffer, buffer_length, &len)) { + if (!_str2bin (hex, FALSE, ":", buffer, buffer_length, &len)) { g_free (buffer); return NULL; } @@ -4333,8 +4290,6 @@ nm_utils_is_uuid (const char *str) const char *p = str; int num_dashes = 0; - g_return_val_if_fail (str, FALSE); - while (*p) { if (*p == '-') num_dashes++; @@ -4510,7 +4465,7 @@ _nm_utils_dhcp_duid_valid (const char *duid, GBytes **out_duid_bin) return TRUE; } - if (_nm_utils_str2bin_full (duid, FALSE, ":", duid_arr, sizeof (duid_arr), &duid_len)) { + if (_str2bin (duid, FALSE, ":", 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)) { @@ -4931,7 +4886,7 @@ nm_utils_enum_from_str (GType type, const char *str, * * Since: 1.2 */ -const char **nm_utils_enum_get_values (GType type, int from, int to) +const char **nm_utils_enum_get_values (GType type, gint from, gint to) { return _nm_utils_enum_get_values (type, from, to); } @@ -5584,7 +5539,7 @@ _nm_utils_team_config_get (const char *conf, g_ptr_array_free (data, TRUE); } else if (json_is_array (json_element)) { - GPtrArray *data = g_ptr_array_new_with_free_func (g_free); + GPtrArray *data = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free); json_t *str_element; int index; @@ -6035,9 +5990,7 @@ attribute_unescape (const char *start, const char *end) * Parse attributes from a string. * * Returns: (transfer full) (element-type utf8 GVariant): a #GHashTable mapping - * attribute names to #GVariant values. Warning: the variant are still floating - * references, owned by the hash table. If you take a reference, ensure to sink - * the one of the hash table first. + * attribute names to #GVariant values. * * Since: 1.8 */ @@ -6194,21 +6147,44 @@ next: return g_steal_pointer (&ht); } -void -_nm_utils_format_variant_attributes_full (GString *str, - const NMUtilsNamedValue *values, - guint num_values, - char attr_separator, - char key_value_separator) +/* + * nm_utils_format_variant_attributes: + * @attributes: (element-type utf8 GVariant): a #GHashTable mapping attribute names to #GVariant values + * @attr_separator: the attribute separator character + * @key_value_separator: character separating key and values + * + * Format attributes to a string. + * + * Returns: (transfer full): the string representing attributes, or %NULL + * in case there are no attributes + * + * Since: 1.8 + */ +char * +nm_utils_format_variant_attributes (GHashTable *attributes, + char attr_separator, + char key_value_separator) { - const char *name, *value; + GString *str = NULL; GVariant *variant; + char sep = 0; + const char *name, *value; char *escaped; char buf[64]; - char sep = 0; - guint i; + gs_free NMUtilsNamedValue *values = NULL; + guint i, len; + + g_return_val_if_fail (attr_separator, NULL); + g_return_val_if_fail (key_value_separator, NULL); - for (i = 0; i < num_values; i++) { + if (!attributes || !g_hash_table_size (attributes)) + return NULL; + + values = nm_utils_named_values_from_str_dict (attributes, &len); + + str = g_string_new (""); + + for (i = 0; i < len; i++) { name = values[i].name; variant = (GVariant *) values[i].value_ptr; value = NULL; @@ -6241,44 +6217,7 @@ _nm_utils_format_variant_attributes_full (GString *str, sep = attr_separator; } -} - -/* - * nm_utils_format_variant_attributes: - * @attributes: (element-type utf8 GVariant): a #GHashTable mapping attribute names to #GVariant values - * @attr_separator: the attribute separator character - * @key_value_separator: character separating key and values - * - * Format attributes to a string. - * - * Returns: (transfer full): the string representing attributes, or %NULL - * in case there are no attributes - * - * Since: 1.8 - */ -char * -nm_utils_format_variant_attributes (GHashTable *attributes, - char attr_separator, - char key_value_separator) -{ - GString *str = NULL; - gs_free NMUtilsNamedValue *values = NULL; - guint len; - g_return_val_if_fail (attr_separator, NULL); - g_return_val_if_fail (key_value_separator, NULL); - - if (!attributes || !g_hash_table_size (attributes)) - return NULL; - - values = nm_utils_named_values_from_str_dict (attributes, &len); - - str = g_string_new (""); - _nm_utils_format_variant_attributes_full (str, - values, - len, - attr_separator, - key_value_separator); return g_string_free (str, FALSE); } |