diff --git a/ChangeLog b/ChangeLog
index 9829a50827..7b8e5e463f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,47 @@
+2006-01-11  Dan Williams  <dcbw@redhat.com>
+
+	Add options for WPA2 and WPA1+CCMP (AES).
+
+	* gnome/applet/wireless-applet.glade
+		- Add UI bits for WPA+CCMP
+
+	* gnome/applet/other-network-dialog.c
+		- (nmwa_ond_init): pass capabilities into the WirelessSecurityManager,
+			and don't allow creation of WPA2 Ad-Hoc networks since
+			wpa_supplicant doesn't support them
+
+	* gnome/applet/wireless-security-manager.c
+		- (wsm_set_capabilities): Add WPA2 options, and pass capability
+			on to the specific wireless security option being created
+
+	* gnome/applet/wireless-security-option.[ch]
+		- (wso_wpa_create_key_type_model): new utility function to create
+			the model required for WPA Key Type combo box
+
+	* gnome/applet/wso-private.h
+	  gnome/applet/wireless-security-option.h
+		- Move private function prototypes into wso-private.h
+
+	* gnome/applet/wso-wpa-psk-hex.[ch]
+	  gnome/applet/wso-wpa-psk-passphrase.[ch]
+		- (append_dbus_params_func): get WPA version from checkbox and pass
+			it to the dbus serialization helper
+		- (key_type_combo_changed_cb): Set the cipher's WE Cipher when the
+			key type combo changes
+		- (wso_wpa_psk_hex_new): set up the key type combo with the correct
+			model and options
+
+	* libnm-util/cipher-wpa-psk-hex.c
+	  libnm-util/cipher-wpa-psk-passphrase.c
+		- (cipher_wpa_psk_hex_set_we_cipher, cipher_wpa_psk_passphrase_set_we_cipher):
+			new function; allow the cipher to be changed after object creation
+
+	* src/nm-ap-security-wpa-psk.c
+		- (set_description): Do WPA2 descriptions too
+
+	* src/nm-ap-security.c
+		- (nm_ap_security_new_from_ap): allow CCMP with WPA1 too
+
 2006-01-11  Robert Love  <rml@novell.com>
 
 	* src/nm-device-802-3-ethernet.c: Use the if_mii() inline function that
diff --git a/gnome/applet/other-network-dialog.c b/gnome/applet/other-network-dialog.c
index 64606b5a5b..e2ee2be677 100644
--- a/gnome/applet/other-network-dialog.c
+++ b/gnome/applet/other-network-dialog.c
@@ -273,6 +273,7 @@ static GtkDialog *nmwa_ond_init (GladeXML *xml, NMWirelessApplet *applet, gboole
 	GtkTreeIter				iter;
 	NetworkDevice *			dev;
 	char *					str;
+	int						dev_caps;
 
 	g_return_val_if_fail (xml != NULL, NULL);
 	g_return_val_if_fail (applet != NULL, NULL);
@@ -329,7 +330,13 @@ static GtkDialog *nmwa_ond_init (GladeXML *xml, NMWirelessApplet *applet, gboole
 	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter);
 	gtk_tree_model_get (model, &iter, NAME_COLUMN, &str, DEV_COLUMN, &dev, -1);
 	g_assert (dev);
-	wsm_set_capabilities (wsm, network_device_get_type_capabilities (dev));
+	dev_caps = network_device_get_type_capabilities (dev);
+	/* Can't do WPA2/CCMP Ad-Hoc networks because wpa_supplicant
+	 * doesn't support them.
+	 */
+	if (create_network)
+		dev_caps &= ~NM_802_11_CAP_PROTO_WPA2;
+	wsm_set_capabilities (wsm, dev_caps);
 
 	security_combo = GTK_COMBO_BOX (glade_xml_get_widget (xml, "security_combo"));
 	wsm_update_combo (wsm, security_combo);
diff --git a/gnome/applet/wireless-applet.glade b/gnome/applet/wireless-applet.glade
index 0bda3d8687..b1027f6a2a 100644
--- a/gnome/applet/wireless-applet.glade
+++ b/gnome/applet/wireless-applet.glade
@@ -2014,11 +2014,14 @@ Shared Key</property>
       <property name="enable_popup">False</property>
 
       <child>
-	<widget class="GtkHBox" id="hbox6">
+	<widget class="GtkTable" id="table8">
 	  <property name="border_width">8</property>
 	  <property name="visible">True</property>
+	  <property name="n_rows">3</property>
+	  <property name="n_columns">2</property>
 	  <property name="homogeneous">False</property>
-	  <property name="spacing">0</property>
+	  <property name="row_spacing">4</property>
+	  <property name="column_spacing">4</property>
 
 	  <child>
 	    <widget class="GtkLabel" id="wpa_psk_hex_label">
@@ -2039,9 +2042,12 @@ Shared Key</property>
 	      <property name="angle">0</property>
 	    </widget>
 	    <packing>
-	      <property name="padding">6</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
+	      <property name="left_attach">0</property>
+	      <property name="right_attach">1</property>
+	      <property name="top_attach">0</property>
+	      <property name="bottom_attach">1</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
 	    </packing>
 	  </child>
 
@@ -2058,9 +2064,78 @@ Shared Key</property>
 	      <property name="activates_default">False</property>
 	    </widget>
 	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">0</property>
+	      <property name="bottom_attach">1</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkCheckButton" id="wpa2_checkbutton">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">Use WPA Enterprise (WPA2)</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">False</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">2</property>
+	      <property name="bottom_attach">3</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="wpa_psk_hex_type_label">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Type:</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">1</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">0</property>
+	      <property name="right_attach">1</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">2</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkComboBox" id="wpa_psk_hex_type_combo">
+	      <property name="visible">True</property>
+	      <property name="items" translatable="yes"></property>
+	      <property name="add_tearoffs">False</property>
+	      <property name="focus_on_click">True</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">2</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options">fill</property>
 	    </packing>
 	  </child>
 	</widget>
@@ -2338,11 +2413,14 @@ Shared Key</property>
       <property name="enable_popup">False</property>
 
       <child>
-	<widget class="GtkHBox" id="hbox8">
+	<widget class="GtkTable" id="table10">
 	  <property name="border_width">8</property>
 	  <property name="visible">True</property>
+	  <property name="n_rows">3</property>
+	  <property name="n_columns">2</property>
 	  <property name="homogeneous">False</property>
-	  <property name="spacing">0</property>
+	  <property name="row_spacing">4</property>
+	  <property name="column_spacing">4</property>
 
 	  <child>
 	    <widget class="GtkLabel" id="wpa_psk_passphrase_label">
@@ -2363,9 +2441,12 @@ Shared Key</property>
 	      <property name="angle">0</property>
 	    </widget>
 	    <packing>
-	      <property name="padding">6</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
+	      <property name="left_attach">0</property>
+	      <property name="right_attach">1</property>
+	      <property name="top_attach">0</property>
+	      <property name="bottom_attach">1</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
 	    </packing>
 	  </child>
 
@@ -2382,9 +2463,78 @@ Shared Key</property>
 	      <property name="activates_default">False</property>
 	    </widget>
 	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">0</property>
+	      <property name="bottom_attach">1</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkCheckButton" id="wpa2_checkbutton">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">Use WPA Enterprise (WPA2)</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">False</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">2</property>
+	      <property name="bottom_attach">3</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="wpa_psk_passphrase_type_label">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Type:</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">1</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">0</property>
+	      <property name="right_attach">1</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">2</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkComboBox" id="wpa_psk_passphrase_type_combo">
+	      <property name="visible">True</property>
+	      <property name="items" translatable="yes"></property>
+	      <property name="add_tearoffs">False</property>
+	      <property name="focus_on_click">True</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">2</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options">fill</property>
 	    </packing>
 	  </child>
 	</widget>
diff --git a/gnome/applet/wireless-security-manager.c b/gnome/applet/wireless-security-manager.c
index 6f79de3fe1..66ac1b6725 100644
--- a/gnome/applet/wireless-security-manager.c
+++ b/gnome/applet/wireless-security-manager.c
@@ -89,13 +89,14 @@ void wsm_set_capabilities (WirelessSecurityManager *wsm, guint32 capabilities)
 		wsm->options = g_slist_append (wsm->options, opt);
 	}
 
-	if (capabilities & NM_802_11_CAP_PROTO_WPA)
+	if (   (capabilities & NM_802_11_CAP_PROTO_WPA)
+	    || (capabilities & NM_802_11_CAP_PROTO_WPA2))
 	{
-		opt = wso_wpa_psk_passphrase_new (wsm->glade_file);
+		opt = wso_wpa_psk_passphrase_new (wsm->glade_file, capabilities);
 		g_assert (opt);
 		wsm->options = g_slist_append (wsm->options, opt);
 
-		opt = wso_wpa_psk_hex_new (wsm->glade_file);
+		opt = wso_wpa_psk_hex_new (wsm->glade_file, capabilities);
 		g_assert (opt);
 		wsm->options = g_slist_append (wsm->options, opt);
 	}
diff --git a/gnome/applet/wireless-security-option.c b/gnome/applet/wireless-security-option.c
index 778084f817..5fdc08313d 100644
--- a/gnome/applet/wireless-security-option.c
+++ b/gnome/applet/wireless-security-option.c
@@ -30,6 +30,7 @@
 #include "wireless-security-option.h"
 #include "cipher.h"
 #include "wso-private.h"
+#include "NetworkManager.h"
 
 gboolean wso_is_wso_widget (GtkWidget * widget)
 {
@@ -193,3 +194,38 @@ void wso_wep_auth_combo_cleanup (WirelessSecurityOption *opt, GtkComboBox * comb
 	g_object_unref (G_OBJECT (model));
 }
 
+
+GtkTreeModel *
+wso_wpa_create_key_type_model (int capabilities,
+                               int *num_added)
+{
+	GtkListStore *	model;
+	GSList *		elt;
+	GtkTreeIter	iter;
+	int			num = 0;
+
+	g_return_val_if_fail (num_added != NULL, NULL);
+
+	model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+	if (capabilities & NM_802_11_CAP_CIPHER_TKIP)
+	{
+		const char *name = _("TKIP (Default)");
+
+		gtk_list_store_append (model, &iter);
+		gtk_list_store_set (model, &iter, WPA_KEY_TYPE_NAME_COL, name,
+			WPA_KEY_TYPE_CIPHER_COL, IW_AUTH_CIPHER_TKIP, -1);
+		num++;
+	}
+	if (capabilities & NM_802_11_CAP_CIPHER_CCMP)
+	{
+		const char *name = _("CCMP/AES");
+
+		gtk_list_store_append (model, &iter);
+		gtk_list_store_set (model, &iter, WPA_KEY_TYPE_NAME_COL, name,
+			WPA_KEY_TYPE_CIPHER_COL, IW_AUTH_CIPHER_CCMP, -1);
+		num++;
+	}
+
+	*num_added = num;
+	return GTK_TREE_MODEL (model);
+}
diff --git a/gnome/applet/wireless-security-option.h b/gnome/applet/wireless-security-option.h
index 510a155cc2..e85139a7d3 100644
--- a/gnome/applet/wireless-security-option.h
+++ b/gnome/applet/wireless-security-option.h
@@ -41,13 +41,4 @@ gboolean		wso_append_dbus_params (WirelessSecurityOption *opt, const char *ssid,
 
 void			wso_free (WirelessSecurityOption * opt);
 
-/* For use by the options themselves */
-gboolean		wso_validate_helper (WirelessSecurityOption *opt, const char *ssid, const char *input, IEEE_802_11_Cipher ** out_cipher);
-GtkWidget *	wso_widget_helper (WirelessSecurityOption *opt);
-
-void			wso_wep_auth_combo_setup (WirelessSecurityOption *opt, GtkComboBox * combo);
-int			wso_wep_auth_combo_get_auth_alg (WirelessSecurityOption *opt, GtkComboBox * combo);
-void			wso_wep_auth_combo_cleanup (WirelessSecurityOption *opt, GtkComboBox * combo);
-
-
 #endif	/* WIRELESS_SECURITY_OPTION_H */
diff --git a/gnome/applet/wso-private.h b/gnome/applet/wso-private.h
index 77e2c6b431..d3e248f7fb 100644
--- a/gnome/applet/wso-private.h
+++ b/gnome/applet/wso-private.h
@@ -69,4 +69,17 @@ struct WirelessSecurityOption
 };
 
 
+gboolean		wso_validate_helper (WirelessSecurityOption *opt, const char *ssid, const char *input, IEEE_802_11_Cipher ** out_cipher);
+GtkWidget *	wso_widget_helper (WirelessSecurityOption *opt);
+
+void			wso_wep_auth_combo_setup (WirelessSecurityOption *opt, GtkComboBox * combo);
+int			wso_wep_auth_combo_get_auth_alg (WirelessSecurityOption *opt, GtkComboBox * combo);
+void			wso_wep_auth_combo_cleanup (WirelessSecurityOption *opt, GtkComboBox * combo);
+
+#define WPA_KEY_TYPE_NAME_COL		0
+#define WPA_KEY_TYPE_CIPHER_COL	1
+
+GtkTreeModel *	wso_wpa_create_key_type_model (int capabilities, int *num_added);
+
+
 #endif	/* WIRELESS_SECURITY_OPTION_PRIVATE_H */
diff --git a/gnome/applet/wso-wpa-psk-hex.c b/gnome/applet/wso-wpa-psk-hex.c
index 7fe52dd59d..767c7bb6ee 100644
--- a/gnome/applet/wso-wpa-psk-hex.c
+++ b/gnome/applet/wso-wpa-psk-hex.c
@@ -32,11 +32,14 @@
 #include "cipher.h"
 #include "cipher-wpa-psk-hex.h"
 #include "dbus-helpers.h"
+#include "NetworkManager.h"
 
 
 struct OptData
 {
 	const char *	entry_name;
+	const char *	wpa2_checkbox_name;
+	const char *	key_type_combo_name;
 };
 
 static void data_free_func (WirelessSecurityOption *opt)
@@ -84,6 +87,8 @@ static gboolean append_dbus_params_func (WirelessSecurityOption *opt, const char
 	int					auth_alg = -1;
 	GtkWidget *			entry;
 	const char *			input;
+	GtkWidget *			wpa2_checkbox;
+	int					wpa_version = IW_AUTH_WPA_VERSION_WPA;
 
 	g_return_val_if_fail (opt != NULL, FALSE);
 	g_return_val_if_fail (opt->data != NULL, FALSE);
@@ -94,23 +99,58 @@ static gboolean append_dbus_params_func (WirelessSecurityOption *opt, const char
 	if (!wso_validate_helper (opt, ssid, input, &cipher) || !cipher)
 		return FALSE;
 
+	wpa2_checkbox = glade_xml_get_widget (opt->uixml, opt->data->wpa2_checkbox_name);
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (wpa2_checkbox)))
+		wpa_version = IW_AUTH_WPA_VERSION_WPA2;
+
 	nmu_security_serialize_wpa_psk_with_cipher (message, cipher, ssid, input,
-			IW_AUTH_WPA_VERSION_WPA, IW_AUTH_KEY_MGMT_PSK);
+			wpa_version, IW_AUTH_KEY_MGMT_PSK);
 
 	return TRUE;
 }
 
 
-WirelessSecurityOption * wso_wpa_psk_hex_new (const char *glade_file)
+static void
+key_type_combo_changed_cb (GtkComboBox *combo,
+                                   gpointer user_data)
+{
+	WirelessSecurityOption * opt = (WirelessSecurityOption *) user_data;
+	IEEE_802_11_Cipher *	cipher;
+	int					we_cipher;
+	GtkTreeModel *			model;
+	GtkTreeIter			iter;
+	char *				str;
+
+	g_return_if_fail (opt != NULL);
+
+	cipher = (IEEE_802_11_Cipher *) g_slist_nth_data (opt->ciphers, 0);
+	g_return_if_fail (cipher != NULL);
+
+	model = gtk_combo_box_get_model (combo);
+	gtk_combo_box_get_active_iter (combo, &iter);
+	gtk_tree_model_get (model, &iter, WPA_KEY_TYPE_NAME_COL, &str,
+			WPA_KEY_TYPE_CIPHER_COL, &we_cipher, -1);
+	cipher_wpa_psk_hex_set_we_cipher (cipher, we_cipher);
+}
+
+
+WirelessSecurityOption *
+wso_wpa_psk_hex_new (const char *glade_file,
+                     int capabilities)
 {
 	WirelessSecurityOption * opt = NULL;
 	GladeXML *			xml = NULL;
 	OptData *				data = NULL;
+	GtkWidget *			wpa2_checkbox;
+	GtkWidget *			key_type_combo;
+	int					num_added;
+	GtkTreeModel *			model;
+	GtkTreeIter			iter;
 
 	g_return_val_if_fail (glade_file != NULL, NULL);
 
 	opt = g_malloc0 (sizeof (WirelessSecurityOption));
-	opt->name = g_strdup (_("WPA Personal Hex"));
+	opt->name = g_strdup (_("WPA Preshared-Key Hex"));
 	opt->widget_name = "wpa_psk_hex_notebook";
 	opt->data_free_func = data_free_func;
 	opt->validate_input_func = validate_input_func;
@@ -127,6 +167,26 @@ WirelessSecurityOption * wso_wpa_psk_hex_new (const char *glade_file)
 	/* Option-specific data */
 	opt->data = data = g_malloc0 (sizeof (OptData));
 	data->entry_name = "wpa_psk_hex_entry";
+	data->wpa2_checkbox_name = "wpa2_checkbutton";
+	data->key_type_combo_name = "wpa_psk_hex_type_combo";
+
+	wpa2_checkbox = glade_xml_get_widget (opt->uixml, data->wpa2_checkbox_name);
+	if (!(capabilities & NM_802_11_CAP_PROTO_WPA2))
+		gtk_widget_set_sensitive (GTK_WIDGET (wpa2_checkbox), FALSE);
+
+	key_type_combo = glade_xml_get_widget (opt->uixml, data->key_type_combo_name);
+	g_signal_connect (G_OBJECT (key_type_combo), "changed", (GCallback) key_type_combo_changed_cb, opt);
+	model = wso_wpa_create_key_type_model (capabilities, &num_added);
+	if (!model || !num_added)
+	{
+		wso_free (opt);
+		return NULL;
+	}
+	gtk_combo_box_set_model (GTK_COMBO_BOX (key_type_combo), model);
+	gtk_tree_model_get_iter_first (model, &iter);
+	gtk_combo_box_set_active_iter (GTK_COMBO_BOX (key_type_combo), &iter);
+	if (num_added == 1)
+		gtk_widget_set_sensitive (key_type_combo, FALSE);
 
 	return opt;
 }
diff --git a/gnome/applet/wso-wpa-psk-hex.h b/gnome/applet/wso-wpa-psk-hex.h
index 6e5996da3a..5c0ea41524 100644
--- a/gnome/applet/wso-wpa-psk-hex.h
+++ b/gnome/applet/wso-wpa-psk-hex.h
@@ -22,7 +22,7 @@
 #ifndef WSO_WPA_PSK_HEX_H
 #define WSO_WPA_PSK_HEX_H
 
-WirelessSecurityOption * wso_wpa_psk_hex_new (const char *glade_file);
+WirelessSecurityOption * wso_wpa_psk_hex_new (const char *glade_file, int capabilities);
 
 
 #endif	/* WSO_WPA_PSK_HEX_H */
diff --git a/gnome/applet/wso-wpa-psk-passphrase.c b/gnome/applet/wso-wpa-psk-passphrase.c
index 5a9b795b3b..a8e23e319f 100644
--- a/gnome/applet/wso-wpa-psk-passphrase.c
+++ b/gnome/applet/wso-wpa-psk-passphrase.c
@@ -32,11 +32,14 @@
 #include "cipher.h"
 #include "cipher-wpa-psk-passphrase.h"
 #include "dbus-helpers.h"
+#include "NetworkManager.h"
 
 
 struct OptData
 {
 	const char *	entry_name;
+	const char *	wpa2_checkbox_name;
+	const char *	key_type_combo_name;
 };
 
 static void data_free_func (WirelessSecurityOption *opt)
@@ -84,6 +87,8 @@ static gboolean append_dbus_params_func (WirelessSecurityOption *opt, const char
 	int					auth_alg = -1;
 	GtkWidget *			entry;
 	const char *			input;
+	GtkWidget *			wpa2_checkbox;
+	int					wpa_version = IW_AUTH_WPA_VERSION_WPA;
 
 	g_return_val_if_fail (opt != NULL, FALSE);
 	g_return_val_if_fail (opt->data != NULL, FALSE);
@@ -94,23 +99,58 @@ static gboolean append_dbus_params_func (WirelessSecurityOption *opt, const char
 	if (!wso_validate_helper (opt, ssid, input, &cipher) || !cipher)
 		return FALSE;
 
+	wpa2_checkbox = glade_xml_get_widget (opt->uixml, opt->data->wpa2_checkbox_name);
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (wpa2_checkbox)))
+		wpa_version = IW_AUTH_WPA_VERSION_WPA2;
+
 	nmu_security_serialize_wpa_psk_with_cipher (message, cipher, ssid, input,
-			IW_AUTH_WPA_VERSION_WPA, IW_AUTH_KEY_MGMT_PSK);
+			wpa_version, IW_AUTH_KEY_MGMT_PSK);
 
 	return TRUE;
 }
 
 
-WirelessSecurityOption * wso_wpa_psk_passphrase_new (const char *glade_file)
+static void
+key_type_combo_changed_cb (GtkComboBox *combo,
+                                   gpointer user_data)
+{
+	WirelessSecurityOption * opt = (WirelessSecurityOption *) user_data;
+	IEEE_802_11_Cipher *	cipher;
+	int					we_cipher;
+	GtkTreeModel *			model;
+	GtkTreeIter			iter;
+	char *				str;
+
+	g_return_if_fail (opt != NULL);
+
+	cipher = (IEEE_802_11_Cipher *) g_slist_nth_data (opt->ciphers, 0);
+	g_return_if_fail (cipher != NULL);
+
+	model = gtk_combo_box_get_model (combo);
+	gtk_combo_box_get_active_iter (combo, &iter);
+	gtk_tree_model_get (model, &iter, WPA_KEY_TYPE_NAME_COL, &str,
+			WPA_KEY_TYPE_CIPHER_COL, &we_cipher, -1);
+	cipher_wpa_psk_passphrase_set_we_cipher (cipher, we_cipher);
+}
+
+
+WirelessSecurityOption *
+wso_wpa_psk_passphrase_new (const char *glade_file,
+                            int capabilities)
 {
 	WirelessSecurityOption * opt = NULL;
 	GladeXML *			xml = NULL;
 	OptData *				data = NULL;
+	GtkWidget *			wpa2_checkbox;
+	GtkWidget *			key_type_combo;
+	int					num_added;
+	GtkTreeModel *			model;
+	GtkTreeIter			iter;
 
 	g_return_val_if_fail (glade_file != NULL, NULL);
 
 	opt = g_malloc0 (sizeof (WirelessSecurityOption));
-	opt->name = g_strdup (_("WPA Personal Passphrase"));
+	opt->name = g_strdup (_("WPA Preshared-Key Passphrase"));
 	opt->widget_name = "wpa_psk_passphrase_notebook";
 	opt->data_free_func = data_free_func;
 	opt->validate_input_func = validate_input_func;
@@ -127,6 +167,26 @@ WirelessSecurityOption * wso_wpa_psk_passphrase_new (const char *glade_file)
 	/* Option-specific data */
 	opt->data = data = g_malloc0 (sizeof (OptData));
 	data->entry_name = "wpa_psk_passphrase_entry";
+	data->wpa2_checkbox_name = "wpa2_checkbutton";
+	data->key_type_combo_name = "wpa_psk_passphrase_type_combo";
+
+	wpa2_checkbox = glade_xml_get_widget (opt->uixml, data->wpa2_checkbox_name);
+	if (!(capabilities & NM_802_11_CAP_PROTO_WPA2))
+		gtk_widget_set_sensitive (GTK_WIDGET (wpa2_checkbox), FALSE);
+
+	key_type_combo = glade_xml_get_widget (opt->uixml, data->key_type_combo_name);
+	g_signal_connect (G_OBJECT (key_type_combo), "changed", (GCallback) key_type_combo_changed_cb, opt);
+	model = wso_wpa_create_key_type_model (capabilities, &num_added);
+	if (!model || !num_added)
+	{
+		wso_free (opt);
+		return NULL;
+	}
+	gtk_combo_box_set_model (GTK_COMBO_BOX (key_type_combo), model);
+	gtk_tree_model_get_iter_first (model, &iter);
+	gtk_combo_box_set_active_iter (GTK_COMBO_BOX (key_type_combo), &iter);
+	if (num_added == 1)
+		gtk_widget_set_sensitive (key_type_combo, FALSE);
 
 	return opt;
 }
diff --git a/gnome/applet/wso-wpa-psk-passphrase.h b/gnome/applet/wso-wpa-psk-passphrase.h
index 39f03afdfe..6942bed2fa 100644
--- a/gnome/applet/wso-wpa-psk-passphrase.h
+++ b/gnome/applet/wso-wpa-psk-passphrase.h
@@ -22,7 +22,7 @@
 #ifndef WSO_WPA_PSK_PASSPHRASE_H
 #define WSO_WPA_PSK_PASSPHRASE_H
 
-WirelessSecurityOption * wso_wpa_psk_passphrase_new (const char *glade_file);
+WirelessSecurityOption * wso_wpa_psk_passphrase_new (const char *glade_file, int capabilities);
 
 
 #endif	/* WSO_WPA_PSK_PASSPHRASE_H */
diff --git a/libnm-util/cipher-wpa-psk-hex.c b/libnm-util/cipher-wpa-psk-hex.c
index 8bba2d098d..328389818c 100644
--- a/libnm-util/cipher-wpa-psk-hex.c
+++ b/libnm-util/cipher-wpa-psk-hex.c
@@ -45,6 +45,17 @@ IEEE_802_11_Cipher * cipher_wpa_psk_hex_new (void)
 	return cipher;
 }
 
+
+void cipher_wpa_psk_hex_set_we_cipher (IEEE_802_11_Cipher *cipher, int we_cipher)
+{
+	g_return_if_fail (cipher != NULL);
+	g_return_if_fail ((we_cipher == IW_AUTH_CIPHER_TKIP) || (we_cipher == IW_AUTH_CIPHER_CCMP));
+	g_return_if_fail ((cipher->we_cipher == IW_AUTH_CIPHER_TKIP) || (cipher->we_cipher == IW_AUTH_CIPHER_CCMP));
+
+	cipher->we_cipher = we_cipher;
+}
+
+
 static char * cipher_wpa_psk_hex_hash_func (IEEE_802_11_Cipher *cipher, const char *ssid, const char *input)
 {
 	char * bin = NULL;
diff --git a/libnm-util/cipher-wpa-psk-hex.h b/libnm-util/cipher-wpa-psk-hex.h
index 6052c61078..6db379e6d3 100644
--- a/libnm-util/cipher-wpa-psk-hex.h
+++ b/libnm-util/cipher-wpa-psk-hex.h
@@ -26,4 +26,6 @@
 
 IEEE_802_11_Cipher * cipher_wpa_psk_hex_new (void);
 
+void cipher_wpa_psk_hex_set_we_cipher (IEEE_802_11_Cipher *cipher, int we_cipher);
+
 #endif	/* CIPHER_WPA_PSK_HEX_H */
diff --git a/libnm-util/cipher-wpa-psk-passphrase.c b/libnm-util/cipher-wpa-psk-passphrase.c
index 9662faea2b..187a5e375a 100644
--- a/libnm-util/cipher-wpa-psk-passphrase.c
+++ b/libnm-util/cipher-wpa-psk-passphrase.c
@@ -46,6 +46,17 @@ IEEE_802_11_Cipher * cipher_wpa_psk_passphrase_new (void)
 	return cipher;
 }
 
+
+void cipher_wpa_psk_passphrase_set_we_cipher (IEEE_802_11_Cipher *cipher, int we_cipher)
+{
+	g_return_if_fail (cipher != NULL);
+	g_return_if_fail ((we_cipher == IW_AUTH_CIPHER_TKIP) || (we_cipher == IW_AUTH_CIPHER_CCMP));
+	g_return_if_fail ((cipher->we_cipher == IW_AUTH_CIPHER_TKIP) || (cipher->we_cipher == IW_AUTH_CIPHER_CCMP));
+
+	cipher->we_cipher = we_cipher;
+}
+
+
 static char * cipher_wpa_psk_passphrase_hash_func (IEEE_802_11_Cipher *cipher, const char *ssid, const char *input)
 {
 	int ssid_len;
diff --git a/libnm-util/cipher-wpa-psk-passphrase.h b/libnm-util/cipher-wpa-psk-passphrase.h
index 668e012e36..ff09434441 100644
--- a/libnm-util/cipher-wpa-psk-passphrase.h
+++ b/libnm-util/cipher-wpa-psk-passphrase.h
@@ -24,4 +24,6 @@
 
 IEEE_802_11_Cipher * cipher_wpa_psk_passphrase_new (void);
 
+void cipher_wpa_psk_passphrase_set_we_cipher (IEEE_802_11_Cipher *cipher, int we_cipher);
+
 #endif	/* CIPHER_WPA_PSK_PASSPHRASE_H */
diff --git a/src/nm-ap-security-wpa-psk.c b/src/nm-ap-security-wpa-psk.c
index 6a3f1cceef..42001eb184 100644
--- a/src/nm-ap-security-wpa-psk.c
+++ b/src/nm-ap-security-wpa-psk.c
@@ -42,11 +42,22 @@ struct _NMAPSecurityWPA_PSKPrivate
 static void set_description (NMAPSecurityWPA_PSK *security)
 {
 	NMAPSecurity * parent = NM_AP_SECURITY (security);
+	int			we_cipher = nm_ap_security_get_we_cipher (parent);
 
-	if (nm_ap_security_get_we_cipher (parent) == IW_AUTH_CIPHER_TKIP)
-		nm_ap_security_set_description (parent, _("WPA TKIP"));
-	else
-		nm_ap_security_set_description (parent, _("WPA CCMP"));
+	if (security->priv->wpa_version == IW_AUTH_WPA_VERSION_WPA)
+	{
+		if (we_cipher == IW_AUTH_CIPHER_TKIP)
+			nm_ap_security_set_description (parent, _("WPA TKIP"));
+		else
+			nm_ap_security_set_description (parent, _("WPA CCMP"));
+	}
+	else if (security->priv->wpa_version == IW_AUTH_WPA_VERSION_WPA2)
+	{
+		if (we_cipher == IW_AUTH_CIPHER_TKIP)
+			nm_ap_security_set_description (parent, _("WPA2 TKIP"));
+		else
+			nm_ap_security_set_description (parent, _("WPA2 CCMP"));
+	}
 }
 
 NMAPSecurityWPA_PSK *
diff --git a/src/nm-ap-security.c b/src/nm-ap-security.c
index 9127f92e0d..7311b9af7d 100644
--- a/src/nm-ap-security.c
+++ b/src/nm-ap-security.c
@@ -102,6 +102,7 @@ out:
 
 #define WPA2_CCMP_PSK	(NM_802_11_CAP_PROTO_WPA2 | NM_802_11_CAP_CIPHER_CCMP | NM_802_11_CAP_KEY_MGMT_PSK)
 #define WPA2_TKIP_PSK	(NM_802_11_CAP_PROTO_WPA2 | NM_802_11_CAP_CIPHER_TKIP | NM_802_11_CAP_KEY_MGMT_PSK)
+#define WPA_CCMP_PSK	(NM_802_11_CAP_PROTO_WPA | NM_802_11_CAP_CIPHER_CCMP | NM_802_11_CAP_KEY_MGMT_PSK)
 #define WPA_TKIP_PSK	(NM_802_11_CAP_PROTO_WPA | NM_802_11_CAP_CIPHER_TKIP | NM_802_11_CAP_KEY_MGMT_PSK)
 #define WEP_WEP104		(NM_802_11_CAP_PROTO_WEP | NM_802_11_CAP_CIPHER_WEP104)
 #define WEP_WEP40		(NM_802_11_CAP_PROTO_WEP | NM_802_11_CAP_CIPHER_WEP40)
@@ -115,7 +116,7 @@ nm_ap_security_new_from_ap (NMAccessPoint *ap)
 
 	/* Deteremine best encryption algorithm to use */
 	caps = nm_ap_get_capabilities (ap);
-	if (caps & WPA2_CCMP_PSK)
+	if ((caps & WPA_CCMP_PSK) || (caps & WPA2_CCMP_PSK))
 		security = NM_AP_SECURITY (nm_ap_security_wpa_psk_new_from_ap (ap, IW_AUTH_CIPHER_CCMP));
 	else if ((caps & WPA_TKIP_PSK) || (caps & WPA2_TKIP_PSK))
 		security = NM_AP_SECURITY (nm_ap_security_wpa_psk_new_from_ap (ap, IW_AUTH_CIPHER_TKIP));
