Blame SOURCES/1009-ifcfg-rh-use-PKCS12-private-as-client-cert-rh1714610.patch

a31528
From 51c47c0a9d77f04d04c6cde7f1254623328898f9 Mon Sep 17 00:00:00 2001
a31528
From: Beniamino Galvani <bgalvani@redhat.com>
a31528
Date: Tue, 14 May 2019 13:59:00 +0200
a31528
Subject: [PATCH 1/3] ifcfg-rh: write client certificate even if it is pkcs12
a31528
a31528
The writer should only persist properties without too much additional
a31528
logic, which should be instead embedded in the setting itself.
a31528
a31528
(cherry picked from commit a995244e9bf526b2d10143858655c3ea3731bf91)
a31528
(cherry picked from commit 5a5cd8d05dfbde11b0983e09a5a37f6929bb2178)
a31528
---
a31528
 .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c    |  4 ----
a31528
 .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c    | 24 ++++++-------------
a31528
 2 files changed, 7 insertions(+), 21 deletions(-)
a31528
a31528
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
a31528
index e5423b181..9b7511064 100644
a31528
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
a31528
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
a31528
@@ -3117,10 +3117,6 @@ eap_tls_reader (const char *eap_method,
a31528
 	                           &client_cert,
a31528
 	                           error))
a31528
 		return FALSE;
a31528
-	/* FIXME: writer does not actually write IEEE_8021X_CLIENT_CERT_PASSWORD and other
a31528
-	 * certificate related passwords. It should, because otherwise persisting such profiles
a31528
-	 * to ifcfg looses information. As this currently only matters for PKCS11 URIs, it seems
a31528
-	 * a seldom used feature so that it is not fixed yet. */
a31528
 	_secret_set_from_ifcfg (s_8021x,
a31528
 	                        ifcfg,
a31528
 	                        keys_ifcfg,
a31528
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
a31528
index 80b1bffe1..90f06e183 100644
a31528
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
a31528
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
a31528
@@ -358,23 +358,13 @@ write_8021x_certs (NMSetting8021x *s_8021x,
a31528
 	if (!write_object (s_8021x, ifcfg, secrets, blobs, otype, error))
a31528
 		return FALSE;
a31528
 
a31528
-	/* Client certificate */
a31528
-	if (otype->vtable->format_func (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
a31528
-		/* Don't need a client certificate with PKCS#12 since the file is both
a31528
-		 * the client certificate and the private key in one file.
a31528
-		 */
a31528
-		svSetValueStr (ifcfg,
a31528
-		               phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT",
a31528
-		               NULL);
a31528
-	} else {
a31528
-		/* Save the client certificate */
a31528
-		if (!write_object (s_8021x, ifcfg, secrets, blobs,
a31528
-		                   phase2
a31528
-		                       ? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT]
a31528
-		                       : &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT],
a31528
-		                   error))
a31528
-			return FALSE;
a31528
-	}
a31528
+	/* Save the client certificate */
a31528
+	if (!write_object (s_8021x, ifcfg, secrets, blobs,
a31528
+	                   phase2
a31528
+	                       ? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT]
a31528
+	                       : &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT],
a31528
+	                   error))
a31528
+		return FALSE;
a31528
 
a31528
 	return TRUE;
a31528
 }
a31528
-- 
a31528
2.20.1
a31528
a31528
From c62a97f608c4c28cbefe1b5b57bec5f6da24b342 Mon Sep 17 00:00:00 2001
a31528
From: Beniamino Galvani <bgalvani@redhat.com>
a31528
Date: Tue, 14 May 2019 14:32:19 +0200
a31528
Subject: [PATCH 2/3] ifcfg-rh: don't check for 802.1x private key or client
a31528
 cert in reader
a31528
a31528
Let the setting check it in verify().
a31528
a31528
(cherry picked from commit d9b3b2b8cec9fdb984a6103240688dc46f33866e)
a31528
(cherry picked from commit c28db67a781388e1f742b3406e26a35c8c2522a8)
a31528
---
a31528
 .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c       | 16 +++-------------
a31528
 1 file changed, 3 insertions(+), 13 deletions(-)
a31528
a31528
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
a31528
index 9b7511064..da3b89e1a 100644
a31528
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
a31528
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
a31528
@@ -3077,6 +3077,7 @@ eap_tls_reader (const char *eap_method,
a31528
 	              svGetValueStr (ifcfg, "IEEE_8021X_IDENTITY", &identity_free),
a31528
 	              NULL);
a31528
 
a31528
+	/* CA certificate */
a31528
 	if (!_cert_set_from_ifcfg (s_8021x,
a31528
 	                           ifcfg,
a31528
 	                           phase2 ? "IEEE_8021X_INNER_CA_CERT" : "IEEE_8021X_CA_CERT",
a31528
@@ -3090,6 +3091,7 @@ eap_tls_reader (const char *eap_method,
a31528
 	                        phase2 ? "IEEE_8021X_INNER_CA_CERT_PASSWORD" : "IEEE_8021X_CA_CERT_PASSWORD",
a31528
 	                        phase2 ? NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD : NM_SETTING_802_1X_CA_CERT_PASSWORD);
a31528
 
a31528
+	/* Private key */
a31528
 	if (!_cert_set_from_ifcfg (s_8021x,
a31528
 	                           ifcfg,
a31528
 	                           phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY",
a31528
@@ -3102,14 +3104,8 @@ eap_tls_reader (const char *eap_method,
a31528
 	                        keys_ifcfg,
a31528
 	                        phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD" : "IEEE_8021X_PRIVATE_KEY_PASSWORD",
a31528
 	                        phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD);
a31528
-	if (!privkey) {
a31528
-		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
a31528
-		             "Missing %s for EAP method '%s'.",
a31528
-		             phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY",
a31528
-		             eap_method);
a31528
-		return FALSE;
a31528
-	}
a31528
 
a31528
+	/* Client certificate */
a31528
 	if (!_cert_set_from_ifcfg (s_8021x,
a31528
 	                           ifcfg,
a31528
 	                           phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT",
a31528
@@ -3122,12 +3118,6 @@ eap_tls_reader (const char *eap_method,
a31528
 	                        keys_ifcfg,
a31528
 	                        phase2 ? "IEEE_8021X_INNER_CLIENT_CERT_PASSWORD" : "IEEE_8021X_CLIENT_CERT_PASSWORD",
a31528
 	                        phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD : NM_SETTING_802_1X_CLIENT_CERT_PASSWORD);
a31528
-	if (!client_cert) {
a31528
-		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
a31528
-		             "Missing certificate for EAP method '%s'.",
a31528
-		             eap_method);
a31528
-		return FALSE;
a31528
-	}
a31528
 
a31528
 	return TRUE;
a31528
 }
a31528
-- 
a31528
2.20.1
a31528
a31528
From b3935bb0f25bede6e9c29735314f42f4bd773e09 Mon Sep 17 00:00:00 2001
a31528
From: Beniamino Galvani <bgalvani@redhat.com>
a31528
Date: Tue, 14 May 2019 15:27:45 +0200
a31528
Subject: [PATCH 3/3] ifcfg-rh: use PKCS #12 private key also as client cert in
a31528
 reader
a31528
a31528
Before commit e3ac45c02610 the reader set the private key in the
a31528
setting using the libnm function, which also set the key as client
a31528
certificate if it was in PKCS #12 format.
a31528
a31528
After the commit, existing connections with a PKCS #12 private key but
a31528
without a client certificate became invalid. Restore the old behavior.
a31528
a31528
Fixes: e3ac45c02610 ('ifcfg-rh: don't use 802-1x certifcate setter functions')
a31528
(cherry picked from commit 9a410fc312c50ac405c57ff4e9eb692e798e248d)
a31528
(cherry picked from commit 51896e1e6b24e0b5d6aefce3c4945d27a5b9f5b7)
a31528
---
a31528
 Makefile.am                                   |   2 ++
a31528
 .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c    |  28 ++++++++++++++++--
a31528
 .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c    |  21 +++++++++----
a31528
 ...fg-test-wired-8021x-tls-p12-no-client-cert |  13 ++++++++
a31528
 .../tests/network-scripts/test_client.p12     | Bin 0 -> 2848 bytes
a31528
 .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c    |  23 ++++++++++++++
a31528
 6 files changed, 79 insertions(+), 8 deletions(-)
a31528
 create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-p12-no-client-cert
a31528
 create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/test_client.p12
a31528
a31528
diff --git a/Makefile.am b/Makefile.am
a31528
index d78bfdeda..8c470df31 100644
a31528
--- a/Makefile.am
a31528
+++ b/Makefile.am
a31528
@@ -3014,6 +3014,7 @@ EXTRA_DIST += \
a31528
 	src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-peap-mschapv2 \
a31528
 	src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-agent \
a31528
 	src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-always \
a31528
+	src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-p12-no-client-cert \
a31528
 	src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-auto-negotiate-on \
a31528
 	src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-autoip \
a31528
 	src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ctc-static \
a31528
@@ -3083,6 +3084,7 @@ EXTRA_DIST += \
a31528
 	src/settings/plugins/ifcfg-rh/tests/network-scripts/route6-test-wired-ipv6-manual \
a31528
 	src/settings/plugins/ifcfg-rh/tests/network-scripts/test1_key_and_cert.pem \
a31528
 	src/settings/plugins/ifcfg-rh/tests/network-scripts/test_ca_cert.pem \
a31528
+	src/settings/plugins/ifcfg-rh/tests/network-scripts/test_client.p12 \
a31528
 	$(NULL)
a31528
 
a31528
 # make target dependencies can't have colons in their names, which ends up
a31528
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
a31528
index da3b89e1a..317e22f7a 100644
a31528
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
a31528
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
a31528
@@ -3071,6 +3071,10 @@ eap_tls_reader (const char *eap_method,
a31528
 	gs_unref_bytes GBytes *privkey = NULL;
a31528
 	gs_unref_bytes GBytes *client_cert = NULL;
a31528
 	gs_free char *identity_free = NULL;
a31528
+	gs_free char *value_to_free = NULL;
a31528
+	const char *client_cert_var;
a31528
+	const char *client_cert_prop;
a31528
+	NMSetting8021xCKFormat format;
a31528
 
a31528
 	g_object_set (s_8021x,
a31528
 	              NM_SETTING_802_1X_IDENTITY,
a31528
@@ -3106,10 +3110,12 @@ eap_tls_reader (const char *eap_method,
a31528
 	                        phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD);
a31528
 
a31528
 	/* Client certificate */
a31528
+	client_cert_var = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT";
a31528
+	client_cert_prop = phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT : NM_SETTING_802_1X_CLIENT_CERT;
a31528
 	if (!_cert_set_from_ifcfg (s_8021x,
a31528
 	                           ifcfg,
a31528
-	                           phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT",
a31528
-	                           phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT : NM_SETTING_802_1X_CLIENT_CERT,
a31528
+	                           client_cert_var,
a31528
+	                           client_cert_prop,
a31528
 	                           &client_cert,
a31528
 	                           error))
a31528
 		return FALSE;
a31528
@@ -3119,6 +3125,24 @@ eap_tls_reader (const char *eap_method,
a31528
 	                        phase2 ? "IEEE_8021X_INNER_CLIENT_CERT_PASSWORD" : "IEEE_8021X_CLIENT_CERT_PASSWORD",
a31528
 	                        phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD : NM_SETTING_802_1X_CLIENT_CERT_PASSWORD);
a31528
 
a31528
+	/* In the past when the private key and client certificate
a31528
+	 * were the same PKCS #12 file we used to write only the
a31528
+	 * private key variable. Still support that even if it means
a31528
+	 * that we have to look into the file content, which makes
a31528
+	 * the connection not self-contained.
a31528
+	 */
a31528
+	if (   !client_cert
a31528
+	    && privkey
a31528
+	    && !svGetValue (ifcfg, client_cert_var, &value_to_free)) {
a31528
+		if (phase2)
a31528
+			format = nm_setting_802_1x_get_phase2_private_key_format (s_8021x);
a31528
+		else
a31528
+			format = nm_setting_802_1x_get_private_key_format (s_8021x);
a31528
+
a31528
+		if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12)
a31528
+			g_object_set (s_8021x, client_cert_prop, privkey, NULL);
a31528
+	}
a31528
+
a31528
 	return TRUE;
a31528
 }
a31528
 
a31528
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
a31528
index 90f06e183..6e2bc8493 100644
a31528
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
a31528
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
a31528
@@ -209,6 +209,7 @@ write_object (NMSetting8021x *s_8021x,
a31528
               GHashTable *secrets,
a31528
               GHashTable *blobs,
a31528
               const Setting8021xSchemeVtable *objtype,
a31528
+              gboolean force_write,
a31528
               GError **error)
a31528
 {
a31528
 	NMSetting8021xCKScheme scheme;
a31528
@@ -287,7 +288,7 @@ write_object (NMSetting8021x *s_8021x,
a31528
 	 */
a31528
 	standard_file = utils_cert_path (svFileGetName (ifcfg), objtype->vtable->file_suffix, extension);
a31528
 	g_hash_table_replace (blobs, standard_file, NULL);
a31528
-	svUnsetValue (ifcfg, objtype->ifcfg_rh_key);
a31528
+	svSetValue (ifcfg, objtype->ifcfg_rh_key, force_write ? "" : NULL);
a31528
 	return TRUE;
a31528
 }
a31528
 
a31528
@@ -338,31 +339,39 @@ write_8021x_certs (NMSetting8021x *s_8021x,
a31528
                    shvarFile *ifcfg,
a31528
                    GError **error)
a31528
 {
a31528
-	const Setting8021xSchemeVtable *otype = NULL;
a31528
+	const Setting8021xSchemeVtable *pk_otype = NULL;
a31528
+	gs_free char *value_to_free = NULL;
a31528
 
a31528
 	/* CA certificate */
a31528
 	if (!write_object (s_8021x, ifcfg, secrets, blobs,
a31528
 	                   phase2
a31528
 	                       ? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT]
a31528
 	                       : &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT],
a31528
+	                   FALSE,
a31528
 	                   error))
a31528
 		return FALSE;
a31528
 
a31528
 	/* Private key */
a31528
 	if (phase2)
a31528
-		otype = &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY];
a31528
+		pk_otype = &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY];
a31528
 	else
a31528
-		otype = &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY];
a31528
+		pk_otype = &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY];
a31528
 
a31528
 	/* Save the private key */
a31528
-	if (!write_object (s_8021x, ifcfg, secrets, blobs, otype, error))
a31528
+	if (!write_object (s_8021x, ifcfg, secrets, blobs, pk_otype, FALSE, error))
a31528
 		return FALSE;
a31528
 
a31528
-	/* Save the client certificate */
a31528
+	/* Save the client certificate.
a31528
+	 * If there is a private key, always write a property for the
a31528
+	 * client certificate even if it is empty, so that the reader
a31528
+	 * doesn't have to read the private key file to determine if it
a31528
+	 * is a PKCS #12 one which serves also as client certificate.
a31528
+	 */
a31528
 	if (!write_object (s_8021x, ifcfg, secrets, blobs,
a31528
 	                   phase2
a31528
 	                       ? &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT]
a31528
 	                       : &setting_8021x_scheme_vtable[NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT],
a31528
+	                   !!svGetValue (ifcfg, pk_otype->ifcfg_rh_key, &value_to_free),
a31528
 	                   error))
a31528
 		return FALSE;
a31528
 
a31528
-- 
a31528
2.20.1
a31528