network-manager-applet r1047 - in trunk: . src/gconf-helpers src/utils



Author: dcbw
Date: Wed Nov 26 03:50:29 2008
New Revision: 1047
URL: http://svn.gnome.org/viewvc/network-manager-applet?rev=1047&view=rev

Log:
2008-11-25  Dan Williams  <dcbw redhat com>

	* src/gconf-helpers/nma-gconf-connection.c
		- (nma_gconf_connection_changed): fill connection certs before functions
			that verify them, since pkcs#12 needs special client cert/private key
			handling; don't leak a connection hash

	* src/utils/utils.c
		- (utils_fill_connection_certs): handle pkcs#12 private keys and set
			client cert at the same time



Modified:
   trunk/ChangeLog
   trunk/src/gconf-helpers/nma-gconf-connection.c
   trunk/src/utils/utils.c

Modified: trunk/src/gconf-helpers/nma-gconf-connection.c
==============================================================================
--- trunk/src/gconf-helpers/nma-gconf-connection.c	(original)
+++ trunk/src/gconf-helpers/nma-gconf-connection.c	Wed Nov 26 03:50:29 2008
@@ -152,8 +152,14 @@
 	if (nm_connection_compare (wrapped_connection, gconf_connection, NM_SETTING_COMPARE_FLAG_EXACT))
 		return TRUE;
 
+	utils_fill_connection_certs (gconf_connection);
 	new_settings = nm_connection_to_hash (gconf_connection);
+	utils_clear_filled_connection_certs (gconf_connection);
+
 	if (!nm_connection_replace_settings (wrapped_connection, new_settings, &error)) {
+		utils_clear_filled_connection_certs (wrapped_connection);
+		g_hash_table_destroy (new_settings);
+
 		g_warning ("%s: '%s' / '%s' invalid: %d",
 		           __func__,
 		           error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(none)",
@@ -162,10 +168,10 @@
 		goto invalid;
 	}
 	g_object_unref (gconf_connection);
+	g_hash_table_destroy (new_settings);
 
 	fill_vpn_user_name (wrapped_connection);
 
-	utils_fill_connection_certs (wrapped_connection);
 	settings = nm_connection_to_hash (wrapped_connection);
 	utils_clear_filled_connection_certs (wrapped_connection);
 

Modified: trunk/src/utils/utils.c
==============================================================================
--- trunk/src/utils/utils.c	(original)
+++ trunk/src/utils/utils.c	Wed Nov 26 03:50:29 2008
@@ -214,12 +214,70 @@
 	return description;
 }
 
+static GByteArray *
+file_to_g_byte_array (const char *filename)
+{
+	char *contents = NULL;
+	GByteArray *array = NULL;
+	gsize length = 0;
+
+	if (!g_file_get_contents (filename, &contents, &length, NULL))
+		return NULL;
+
+	array = g_byte_array_sized_new (length);
+	if (!array) {
+		g_free (contents);
+		return NULL;
+	}
+
+	g_byte_array_append (array, (unsigned char *) contents, length);
+	return array;
+}
+
+static gboolean
+fill_one_private_key (NMConnection *connection,
+                      const char *pk_tag,
+                      const char *pk_prop,
+                      const char *cc_prop)
+{
+	const char *filename;
+	NMSetting8021x *tmp;
+	NMSetting8021xCKType pk_type = NM_SETTING_802_1X_CK_TYPE_UNKNOWN;
+	gboolean need_client_cert = TRUE;
+
+	/* If the private key is PKCS#12, don't set the client cert */
+	filename = g_object_get_data (G_OBJECT (connection), pk_tag);
+	if (!filename)
+		return TRUE;
+
+	tmp = NM_SETTING_802_1X (nm_setting_802_1x_new ());
+	nm_setting_802_1x_set_private_key_from_file (tmp, filename, NULL, &pk_type, NULL);
+	if (pk_type == NM_SETTING_802_1X_CK_TYPE_PKCS12) {
+		GByteArray *array;
+
+		array = file_to_g_byte_array (filename);
+		if (array) {
+			NMSetting *s_8021x = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+
+			g_object_set (s_8021x,
+			              pk_prop, array,
+			              cc_prop, array,
+			              NULL);
+			g_byte_array_free (array, TRUE);
+			need_client_cert = FALSE;
+		}
+	}
+	g_object_unref (tmp);
+	return need_client_cert;
+}
+
 void
 utils_fill_connection_certs (NMConnection *connection)
 {
 	NMSetting8021x *s_8021x;
 	const char *filename;
 	GError *error = NULL;
+	gboolean need_client_cert = TRUE;
 
 	g_return_if_fail (connection != NULL);
 
@@ -234,11 +292,18 @@
 		g_clear_error (&error);
 	}
 
-	filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_CLIENT_CERT_TAG);
-	if (filename) {
-		if (!nm_setting_802_1x_set_client_cert_from_file (s_8021x, filename, NULL, &error))
-			g_warning ("%s: couldn't read client certificate: %d %s", __func__, error->code, error->message);
-		g_clear_error (&error);
+	/* If the private key is PKCS#12, don't set the client cert */
+	need_client_cert = fill_one_private_key (connection,
+	                                         NMA_PATH_PRIVATE_KEY_TAG,
+	                                         NM_SETTING_802_1X_PRIVATE_KEY,
+	                                         NM_SETTING_802_1X_CLIENT_CERT);
+	if (need_client_cert) {
+		filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_CLIENT_CERT_TAG);
+		if (filename) {
+			if (!nm_setting_802_1x_set_client_cert_from_file (s_8021x, filename, NULL, &error))
+				g_warning ("%s: couldn't read client certificate: %d %s", __func__, error->code, error->message);
+			g_clear_error (&error);
+		}
 	}
 
 	filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_PHASE2_CA_CERT_TAG);
@@ -248,11 +313,18 @@
 		g_clear_error (&error);
 	}
 
-	filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_PHASE2_CLIENT_CERT_TAG);
-	if (filename) {
-		if (!nm_setting_802_1x_set_phase2_client_cert_from_file (s_8021x, filename, NULL, &error))
-			g_warning ("%s: couldn't read phase2 client certificate: %d %s", __func__, error->code, error->message);
-		g_clear_error (&error);
+	/* If the private key is PKCS#12, don't set the client cert */
+	need_client_cert = fill_one_private_key (connection,
+	                                         NMA_PATH_PHASE2_PRIVATE_KEY_TAG,
+	                                         NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+	                                         NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
+	if (need_client_cert) {
+		filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_PHASE2_CLIENT_CERT_TAG);
+		if (filename) {
+			if (!nm_setting_802_1x_set_phase2_client_cert_from_file (s_8021x, filename, NULL, &error))
+				g_warning ("%s: couldn't read phase2 client certificate: %d %s", __func__, error->code, error->message);
+			g_clear_error (&error);
+		}
 	}
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]