From 2b09cee6fa145871f56895e420ac38f6ce5cee9b Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 6 Jan 2017 16:00:11 +0100 Subject: [PATCH] libnm-core/8021x: fix up scheme handling in setters Fixes: 690e33bdf287b5952740925d0e208da4d1d3712e --- libnm-core/nm-setting-8021x.c | 95 +++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index 2b386b6fa0..ceaedb84a3 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -644,8 +644,8 @@ value_with_scheme (const char *path, const char *scheme) len = strlen (path); /* Add the path scheme tag to the front, then the filename */ - array = g_byte_array_sized_new (len + strlen (NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH) + 1); - g_byte_array_append (array, (const guint8 *) NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH, strlen (NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH)); + array = g_byte_array_sized_new (len + strlen (scheme) + 1); + g_byte_array_append (array, (const guint8 *) scheme, strlen (scheme)); g_byte_array_append (array, (const guint8 *) path, len); g_byte_array_append (array, (const guint8 *) "\0", 1); @@ -655,7 +655,7 @@ value_with_scheme (const char *path, const char *scheme) /** * nm_setting_802_1x_set_ca_cert: * @setting: the #NMSetting8021x - * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the CA certificate * file (PEM or DER format). The path must be UTF-8 encoded; use * g_filename_to_utf8() to convert if needed. Passing %NULL with any @scheme @@ -1020,7 +1020,7 @@ nm_setting_802_1x_get_client_cert_uri (NMSetting8021x *setting) /** * nm_setting_802_1x_set_client_cert: * @setting: the #NMSetting8021x - * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the client * certificate file (PEM, DER, or PKCS#12 format). The path must be UTF-8 * encoded; use g_filename_to_utf8() to convert if needed. Passing %NULL with @@ -1042,7 +1042,7 @@ nm_setting_802_1x_get_client_cert_uri (NMSetting8021x *setting) **/ gboolean nm_setting_802_1x_set_client_cert (NMSetting8021x *setting, - const char *cert_path, + const char *value, NMSetting8021xCKScheme scheme, NMSetting8021xCKFormat *out_format, GError **error) @@ -1053,8 +1053,8 @@ nm_setting_802_1x_set_client_cert (NMSetting8021x *setting, g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); - if (cert_path) { - g_return_val_if_fail (g_utf8_validate (cert_path, -1, NULL), FALSE); + if (value) { + g_return_val_if_fail (g_utf8_validate (value, -1, NULL), FALSE); g_return_val_if_fail ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH || scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11, @@ -1068,18 +1068,18 @@ nm_setting_802_1x_set_client_cert (NMSetting8021x *setting, g_clear_pointer (&priv->client_cert, g_bytes_unref); - if (!cert_path) { + if (!value) { g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CLIENT_CERT); return TRUE; } if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) { - priv->client_cert = value_with_scheme (cert_path, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); + priv->client_cert = value_with_scheme (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11); g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CLIENT_CERT); return TRUE; } - data = load_and_verify_certificate (cert_path, scheme, &format, error); + data = load_and_verify_certificate (value, scheme, &format, error); if (data) { gboolean valid = FALSE; @@ -1108,7 +1108,7 @@ nm_setting_802_1x_set_client_cert (NMSetting8021x *setting, priv->client_cert = g_byte_array_free_to_bytes (data); data = NULL; } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) - priv->client_cert = value_with_scheme (cert_path, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); + priv->client_cert = value_with_scheme (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); else g_assert_not_reached (); } @@ -1328,7 +1328,7 @@ nm_setting_802_1x_get_phase2_ca_cert_uri (NMSetting8021x *setting) /** * nm_setting_802_1x_set_phase2_ca_cert: * @setting: the #NMSetting8021x - * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" CA * certificate file (PEM or DER format). The path must be UTF-8 encoded; use * g_filename_to_utf8() to convert if needed. Passing %NULL with any @scheme @@ -1346,7 +1346,7 @@ nm_setting_802_1x_get_phase2_ca_cert_uri (NMSetting8021x *setting) **/ gboolean nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *setting, - const char *cert_path, + const char *value, NMSetting8021xCKScheme scheme, NMSetting8021xCKFormat *out_format, GError **error) @@ -1357,10 +1357,11 @@ nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *setting, g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); - if (cert_path) { - g_return_val_if_fail (g_utf8_validate (cert_path, -1, NULL), FALSE); + if (value) { + g_return_val_if_fail (g_utf8_validate (value, -1, NULL), FALSE); g_return_val_if_fail ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB - || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, + || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH + || scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11, FALSE); } @@ -1371,12 +1372,19 @@ nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *setting, g_clear_pointer (&priv->phase2_ca_cert, g_bytes_unref); - if (!cert_path) { + if (!value) { g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CA_CERT); return TRUE; } - data = load_and_verify_certificate (cert_path, scheme, &format, error); + data = load_and_verify_certificate (value, scheme, &format, error); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) { + priv->phase2_ca_cert = value_with_scheme (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CA_CERT); + return TRUE; + } + + data = load_and_verify_certificate (value, scheme, &format, error); if (data) { /* wpa_supplicant can only use raw x509 CA certs */ if (format == NM_CRYPTO_FILE_FORMAT_X509) { @@ -1387,7 +1395,7 @@ nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *setting, priv->phase2_ca_cert = g_byte_array_free_to_bytes (data); data = NULL; } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) - priv->phase2_ca_cert = value_with_scheme (cert_path, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); + priv->phase2_ca_cert = value_with_scheme (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); else g_assert_not_reached (); } else { @@ -1691,7 +1699,7 @@ nm_setting_802_1x_get_phase2_client_cert_uri (NMSetting8021x *setting) /** * nm_setting_802_1x_set_phase2_client_cert: * @setting: the #NMSetting8021x - * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" client * certificate file (PEM, DER, or PKCS#12 format). The path must be UTF-8 * encoded; use g_filename_to_utf8() to convert if needed. Passing %NULL with @@ -1713,7 +1721,7 @@ nm_setting_802_1x_get_phase2_client_cert_uri (NMSetting8021x *setting) **/ gboolean nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *setting, - const char *cert_path, + const char *value, NMSetting8021xCKScheme scheme, NMSetting8021xCKFormat *out_format, GError **error) @@ -1724,10 +1732,11 @@ nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *setting, g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); - if (cert_path) { - g_return_val_if_fail (g_utf8_validate (cert_path, -1, NULL), FALSE); + if (value) { + g_return_val_if_fail (g_utf8_validate (value, -1, NULL), FALSE); g_return_val_if_fail ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB - || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, + || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH + || scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11, FALSE); } @@ -1738,12 +1747,18 @@ nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *setting, g_clear_pointer (&priv->phase2_client_cert, g_bytes_unref); - if (!cert_path) { + if (!value) { g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CLIENT_CERT); return TRUE; } - data = load_and_verify_certificate (cert_path, scheme, &format, error); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) { + priv->phase2_client_cert = value_with_scheme (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + return TRUE; + } + + data = load_and_verify_certificate (value, scheme, &format, error); if (data) { gboolean valid = FALSE; @@ -1773,7 +1788,7 @@ nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *setting, priv->phase2_client_cert = g_byte_array_free_to_bytes (data); data = NULL; } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) - priv->phase2_client_cert = value_with_scheme (cert_path, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); + priv->phase2_client_cert = value_with_scheme (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); else g_assert_not_reached (); } @@ -2009,7 +2024,7 @@ file_to_secure_bytes (const char *filename) /** * nm_setting_802_1x_set_private_key: * @setting: the #NMSetting8021x - * @key_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or * %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the private key file * (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; use * g_filename_to_utf8() to convert if needed. Passing %NULL with any @scheme @@ -2356,7 +2371,7 @@ nm_setting_802_1x_get_phase2_private_key_uri (NMSetting8021x *setting) /** * nm_setting_802_1x_set_phase2_private_key: * @setting: the #NMSetting8021x - * @key_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or + * @value: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or * %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" private * key file (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; * use g_filename_to_utf8() to convert if needed. Passing %NULL with any @@ -2394,7 +2409,7 @@ nm_setting_802_1x_get_phase2_private_key_uri (NMSetting8021x *setting) **/ gboolean nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *setting, - const char *key_path, + const char *value, const char *password, NMSetting8021xCKScheme scheme, NMSetting8021xCKFormat *out_format, @@ -2407,10 +2422,11 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *setting, g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); - if (key_path) { - g_return_val_if_fail (g_utf8_validate (key_path, -1, NULL), FALSE); + if (value) { + g_return_val_if_fail (g_utf8_validate (value, -1, NULL), FALSE); g_return_val_if_fail ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB - || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, + || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH + || scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11, FALSE); } @@ -2420,8 +2436,8 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *setting, /* Ensure the private key is a recognized format and if the password was * given, that it decrypts the private key. */ - if (key_path) { - format = crypto_verify_private_key (key_path, password, NULL, &local_err); + if (value && scheme != NM_SETTING_802_1X_CK_SCHEME_PKCS11) { + format = crypto_verify_private_key (value, password, NULL, &local_err); if (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN) { g_set_error_literal (error, NM_CONNECTION_ERROR, @@ -2448,7 +2464,7 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *setting, password_cleared = TRUE; } - if (key_path == NULL) { + if (value == NULL) { if (key_cleared) g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); if (password_cleared) @@ -2460,17 +2476,18 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *setting, if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { /* FIXME: potential race after verifying the private key above */ /* FIXME: ensure blob doesn't start with file:// */ - priv->phase2_private_key = file_to_secure_bytes (key_path); + priv->phase2_private_key = file_to_secure_bytes (value); g_assert (priv->phase2_private_key); } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) - priv->phase2_private_key = value_with_scheme (key_path, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); + priv->phase2_private_key = value_with_scheme (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); + else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) + priv->phase2_private_key = value_with_scheme (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11); else g_assert_not_reached (); /* As required by NM and wpa_supplicant, set the client-cert * property to the same PKCS#12 data. */ - g_assert (format != NM_CRYPTO_FILE_FORMAT_UNKNOWN); if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) { if (priv->phase2_client_cert) g_bytes_unref (priv->phase2_client_cert);