[network-manager-applet] libnm-gtk: add support for TTLS/EAP-MD5 and TTLS/EAP-GTC (bgo #729671)



commit 2294732eb608fad0ad65e315e1495094c0c9f34c
Author: Dan Williams <dcbw redhat com>
Date:   Wed May 14 11:26:04 2014 -0500

    libnm-gtk: add support for TTLS/EAP-MD5 and TTLS/EAP-GTC (bgo #729671)
    
    Add the simple EAP methods MD5 and GTC as inner/phase2 methods for TTLS.
    
    These methods must be inner *EAP* methods too, unlike PAP/CHAP/MSCHAP,
    so we need to update the code to ensure that when they are selected,
    the editor/applet puts them into NM_SETTING_802_1X_PHASE2_AUTHEAP instead
    of NM_SETTING_802_1X_PHASE2_AUTH.  Take the opportunity to clean up
    all the booleans passed into eap_method_simple_new() while we're here
    so that we don't have to add yet another boolean argument.
    
    Inspired by a patch from Pali Rohár <pali rohar gmail com>

 src/wireless-security/eap-method-fast.c   |   14 +++--
 src/wireless-security/eap-method-peap.c   |   19 +++---
 src/wireless-security/eap-method-simple.c |   91 ++++++++++++++---------------
 src/wireless-security/eap-method-simple.h |   22 ++++++-
 src/wireless-security/eap-method-ttls.c   |   54 ++++++++++++++----
 src/wireless-security/wireless-security.c |   16 +++---
 6 files changed, 132 insertions(+), 84 deletions(-)
---
diff --git a/src/wireless-security/eap-method-fast.c b/src/wireless-security/eap-method-fast.c
index 6077495..47f3d70 100644
--- a/src/wireless-security/eap-method-fast.c
+++ b/src/wireless-security/eap-method-fast.c
@@ -240,6 +240,7 @@ inner_auth_combo_init (EAPMethodFAST *method,
        EAPMethodSimple *em_mschap_v2;
        guint32 active = 0;
        const char *phase2_auth = NULL;
+       EAPMethodSimpleFlags simple_flags;
 
        auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ());
 
@@ -250,12 +251,16 @@ inner_auth_combo_init (EAPMethodFAST *method,
                        phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x);
        }
 
+       simple_flags = EAP_METHOD_SIMPLE_FLAG_PHASE2;
+       if (method->is_editor)
+               simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR;
+       if (secrets_only)
+               simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY;
+
        em_gtc = eap_method_simple_new (method->sec_parent,
                                        connection,
                                        EAP_METHOD_SIMPLE_TYPE_GTC,
-                                       TRUE,
-                                       method->is_editor,
-                                       secrets_only);
+                                       simple_flags);
        gtk_list_store_append (auth_model, &iter);
        gtk_list_store_set (auth_model, &iter,
                            I_NAME_COLUMN, _("GTC"),
@@ -270,8 +275,7 @@ inner_auth_combo_init (EAPMethodFAST *method,
        em_mschap_v2 = eap_method_simple_new (method->sec_parent,
                                              connection,
                                              EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2,
-                                             TRUE,
-                                             method->is_editor, secrets_only);
+                                             simple_flags);
        gtk_list_store_append (auth_model, &iter);
        gtk_list_store_set (auth_model, &iter,
                            I_NAME_COLUMN, _("MSCHAPv2"),
diff --git a/src/wireless-security/eap-method-peap.c b/src/wireless-security/eap-method-peap.c
index e88552e..d4fa7db 100644
--- a/src/wireless-security/eap-method-peap.c
+++ b/src/wireless-security/eap-method-peap.c
@@ -243,6 +243,7 @@ inner_auth_combo_init (EAPMethodPEAP *method,
        EAPMethodSimple *em_gtc;
        guint32 active = 0;
        const char *phase2_auth = NULL;
+       EAPMethodSimpleFlags simple_flags;
 
        auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ());
 
@@ -253,12 +254,16 @@ inner_auth_combo_init (EAPMethodPEAP *method,
                        phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x);
        }
 
+       simple_flags = EAP_METHOD_SIMPLE_FLAG_PHASE2;
+       if (method->is_editor)
+               simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR;
+       if (secrets_only)
+               simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY;
+
        em_mschap_v2 = eap_method_simple_new (method->sec_parent,
                                              connection,
                                              EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2,
-                                             TRUE,
-                                             method->is_editor,
-                                             secrets_only);
+                                             simple_flags);
        gtk_list_store_append (auth_model, &iter);
        gtk_list_store_set (auth_model, &iter,
                            I_NAME_COLUMN, _("MSCHAPv2"),
@@ -273,9 +278,7 @@ inner_auth_combo_init (EAPMethodPEAP *method,
        em_md5 = eap_method_simple_new (method->sec_parent,
                                        connection,
                                        EAP_METHOD_SIMPLE_TYPE_MD5,
-                                       TRUE,
-                                       method->is_editor,
-                                       secrets_only);
+                                       simple_flags);
        gtk_list_store_append (auth_model, &iter);
        gtk_list_store_set (auth_model, &iter,
                            I_NAME_COLUMN, _("MD5"),
@@ -290,9 +293,7 @@ inner_auth_combo_init (EAPMethodPEAP *method,
        em_gtc = eap_method_simple_new (method->sec_parent,
                                        connection,
                                        EAP_METHOD_SIMPLE_TYPE_GTC,
-                                       TRUE,
-                                       method->is_editor,
-                                       secrets_only);
+                                       simple_flags);
        gtk_list_store_append (auth_model, &iter);
        gtk_list_store_set (auth_model, &iter,
                            I_NAME_COLUMN, _("GTC"),
diff --git a/src/wireless-security/eap-method-simple.c b/src/wireless-security/eap-method-simple.c
index e23affd..427bb9f 100644
--- a/src/wireless-security/eap-method-simple.c
+++ b/src/wireless-security/eap-method-simple.c
@@ -36,8 +36,7 @@ struct _EAPMethodSimple {
        WirelessSecurity *ws_parent;
 
        EAPMethodSimpleType type;
-       gboolean is_editor;
-       gboolean editing_connection;
+       EAPMethodSimpleFlags flags;
 
        GtkEntry *username_entry;
        GtkEntry *password_entry;
@@ -89,14 +88,30 @@ add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
        gtk_size_group_add_widget (group, widget);
 }
 
+typedef struct {
+       const char *name;
+       gboolean autheap_allowed;
+} EapType;
+
+/* Indexed by EAP_METHOD_SIMPLE_TYPE_* */
+static const EapType eap_table[EAP_METHOD_SIMPLE_TYPE_LAST] = {
+       [EAP_METHOD_SIMPLE_TYPE_PAP]       = { "pap",      FALSE },
+       [EAP_METHOD_SIMPLE_TYPE_MSCHAP]    = { "mschap",   FALSE },
+       [EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2] = { "mschapv2", TRUE  },
+       [EAP_METHOD_SIMPLE_TYPE_MD5]       = { "md5",      TRUE  },
+       [EAP_METHOD_SIMPLE_TYPE_PWD]       = { "pwd",      TRUE  },
+       [EAP_METHOD_SIMPLE_TYPE_CHAP]      = { "chap",     FALSE },
+       [EAP_METHOD_SIMPLE_TYPE_GTC]       = { "gtc",      TRUE  },
+};
+
 static void
 fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags prev_flags)
 {
        EAPMethodSimple *method = (EAPMethodSimple *) parent;
        NMSetting8021x *s_8021x;
        gboolean not_saved = FALSE;
-       const char *eap = NULL;
        NMSettingSecretFlags flags = prev_flags;
+       const EapType *eap_type;
 
        s_8021x = nm_connection_get_setting_802_1x (connection);
        g_assert (s_8021x);
@@ -107,37 +122,22 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
        if (parent->phase2 == FALSE)
                nm_setting_802_1x_clear_eap_methods (s_8021x);
 
-       switch (method->type) {
-               case EAP_METHOD_SIMPLE_TYPE_PAP:
-                       eap = "pap";
-                       break;
-               case EAP_METHOD_SIMPLE_TYPE_MSCHAP:
-                       eap = "mschap";
-                       break;
-               case EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2:
-                       eap = "mschapv2";
-                       break;
-               case EAP_METHOD_SIMPLE_TYPE_MD5:
-                       eap = "md5";
-                       break;
-               case EAP_METHOD_SIMPLE_TYPE_CHAP:
-                       eap = "chap";
-                       break;
-               case EAP_METHOD_SIMPLE_TYPE_GTC:
-                       eap = "gtc";
-                       break;
-               case EAP_METHOD_SIMPLE_TYPE_PWD:
-                       eap = "pwd";
-                       break;
-               default:
-                       g_assert_not_reached ();
-                       break;
-       }
-
-       if (parent->phase2)
-               g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, eap, NULL);
-       else
-               nm_setting_802_1x_add_eap_method (s_8021x, eap);
+       eap_type = &eap_table[method->type];
+       if (parent->phase2) {
+               /* If the outer EAP method (TLS, TTLS, PEAP, etc) allows inner/phase2
+                * EAP methods (which only TTLS allows) *and* the inner/phase2 method
+                * supports being an inner EAP method, then set PHASE2_AUTHEAP.
+                * Otherwise the inner/phase2 method goes into PHASE2_AUTH.
+                */
+               if ((method->flags & EAP_METHOD_SIMPLE_FLAG_AUTHEAP_ALLOWED) && eap_type->autheap_allowed) {
+                       g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, eap_type->name, NULL);
+                       g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, NULL, NULL);
+               } else {
+                       g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, eap_type->name, NULL);
+                       g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, NULL, NULL);
+               }
+       } else
+               nm_setting_802_1x_add_eap_method (s_8021x, eap_type->name);
 
        g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (method->username_entry), NULL);
 
@@ -154,12 +154,11 @@ fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFla
         * back to NM in response to a GetSecrets() call, we don't save it if the
         * user checked "Always Ask".
         */
-       if (method->is_editor == FALSE || not_saved == FALSE) {
+       if (!(method->flags & EAP_METHOD_SIMPLE_FLAG_IS_EDITOR) || not_saved == FALSE)
                g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, gtk_entry_get_text 
(method->password_entry), NULL);
-       }
 
        /* Update secret flags and popup when editing the connection */
-       if (method->editing_connection) {
+       if (!(method->flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY)) {
                GtkWidget *passwd_entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, 
"eap_simple_password_entry"));
                g_assert (passwd_entry);
 
@@ -277,9 +276,7 @@ EAPMethodSimple *
 eap_method_simple_new (WirelessSecurity *ws_parent,
                        NMConnection *connection,
                        EAPMethodSimpleType type,
-                       gboolean phase2,
-                       gboolean is_editor,
-                       gboolean secrets_only)
+                       EAPMethodSimpleFlags flags)
 {
        EAPMethod *parent;
        EAPMethodSimple *method;
@@ -294,16 +291,16 @@ eap_method_simple_new (WirelessSecurity *ws_parent,
                                  UIDIR "/eap-method-simple.ui",
                                  "eap_simple_notebook",
                                  "eap_simple_username_entry",
-                                 phase2);
+                                 flags & EAP_METHOD_SIMPLE_FLAG_PHASE2);
        if (!parent)
                return NULL;
 
        parent->password_flags_name = NM_SETTING_802_1X_PASSWORD;
        method = (EAPMethodSimple *) parent;
-       method->type = type;
-       method->is_editor = is_editor;
-       method->editing_connection = secrets_only ? FALSE : TRUE;
        method->ws_parent = wireless_security_ref (ws_parent);
+       method->flags = flags;
+       method->type = type;
+       g_assert (type < EAP_METHOD_SIMPLE_TYPE_LAST);
 
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_notebook"));
        g_assert (widget);
@@ -321,7 +318,7 @@ eap_method_simple_new (WirelessSecurity *ws_parent,
                          (GCallback) wireless_security_changed_cb,
                          ws_parent);
 
-       if (secrets_only)
+       if (method->flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY)
                gtk_widget_set_sensitive (widget, FALSE);
 
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry"));
@@ -340,7 +337,7 @@ eap_method_simple_new (WirelessSecurity *ws_parent,
        g_signal_connect (G_OBJECT (widget), "toggled",
                          (GCallback) wireless_security_changed_cb,
                          ws_parent);
-       if (is_editor) {
+       if (flags & EAP_METHOD_SIMPLE_FLAG_IS_EDITOR) {
                /* We only desensitize the password entry from the editor, because
                 * from nm-applet if the entry was desensitized, there'd be no way to
                 * get the password back to NetworkManager when NM asked for it.  Since
@@ -352,7 +349,7 @@ eap_method_simple_new (WirelessSecurity *ws_parent,
                                  method);
        }
 
-       if (secrets_only)
+       if (flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY)
                gtk_widget_hide (widget);
 
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapsimple"));
diff --git a/src/wireless-security/eap-method-simple.h b/src/wireless-security/eap-method-simple.h
index 6f43104..293d17b 100644
--- a/src/wireless-security/eap-method-simple.h
+++ b/src/wireless-security/eap-method-simple.h
@@ -26,23 +26,37 @@
 #include "wireless-security.h"
 
 typedef enum {
+       /* NOTE: when updating this table, also update eap_methods[] */
        EAP_METHOD_SIMPLE_TYPE_PAP = 0,
        EAP_METHOD_SIMPLE_TYPE_MSCHAP,
        EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2,
        EAP_METHOD_SIMPLE_TYPE_MD5,
        EAP_METHOD_SIMPLE_TYPE_PWD,
        EAP_METHOD_SIMPLE_TYPE_CHAP,
-       EAP_METHOD_SIMPLE_TYPE_GTC
+       EAP_METHOD_SIMPLE_TYPE_GTC,
+
+       /* Boundary value, do not use */
+       EAP_METHOD_SIMPLE_TYPE_LAST
 } EAPMethodSimpleType;
 
+typedef enum {
+       EAP_METHOD_SIMPLE_FLAG_NONE            = 0x00,
+       /* Indicates the EAP method is an inner/phase2 method */
+       EAP_METHOD_SIMPLE_FLAG_PHASE2          = 0x01,
+       /* Set by TTLS to indicate that inner/phase2 EAP is allowed */
+       EAP_METHOD_SIMPLE_FLAG_AUTHEAP_ALLOWED = 0x02,
+       /* Set from nm-connection-editor or the GNOME network panel */
+       EAP_METHOD_SIMPLE_FLAG_IS_EDITOR       = 0x04,
+       /* Set to indicate that this request is only for secrets */
+       EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY    = 0x08
+} EAPMethodSimpleFlags;
+
 typedef struct _EAPMethodSimple EAPMethodSimple;
 
 EAPMethodSimple *eap_method_simple_new (WirelessSecurity *ws_parent,
                                         NMConnection *connection,
                                         EAPMethodSimpleType type,
-                                        gboolean phase2,
-                                        gboolean is_editor,
-                                        gboolean secrets_only);
+                                        EAPMethodSimpleFlags flags);
 
 #endif /* EAP_METHOD_SIMPLE_H */
 
diff --git a/src/wireless-security/eap-method-ttls.c b/src/wireless-security/eap-method-ttls.c
index d4e0f36..294734d 100644
--- a/src/wireless-security/eap-method-ttls.c
+++ b/src/wireless-security/eap-method-ttls.c
@@ -225,8 +225,11 @@ inner_auth_combo_init (EAPMethodTTLS *method,
        EAPMethodSimple *em_mschap;
        EAPMethodSimple *em_mschap_v2;
        EAPMethodSimple *em_chap;
+       EAPMethodSimple *em_md5;
+       EAPMethodSimple *em_gtc;
        guint32 active = 0;
        const char *phase2_auth = NULL;
+       EAPMethodSimpleFlags simple_flags;
 
        auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ());
 
@@ -237,12 +240,16 @@ inner_auth_combo_init (EAPMethodTTLS *method,
                        phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x);
        }
 
+       simple_flags = EAP_METHOD_SIMPLE_FLAG_PHASE2 | EAP_METHOD_SIMPLE_FLAG_AUTHEAP_ALLOWED;
+       if (method->is_editor)
+               simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR;
+       if (secrets_only)
+               simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY;
+
        em_pap = eap_method_simple_new (method->sec_parent,
                                        connection,
                                        EAP_METHOD_SIMPLE_TYPE_PAP,
-                                       TRUE,
-                                       method->is_editor,
-                                       secrets_only);
+                                       simple_flags);
        gtk_list_store_append (auth_model, &iter);
        gtk_list_store_set (auth_model, &iter,
                            I_NAME_COLUMN, _("PAP"),
@@ -257,9 +264,7 @@ inner_auth_combo_init (EAPMethodTTLS *method,
        em_mschap = eap_method_simple_new (method->sec_parent,
                                           connection,
                                           EAP_METHOD_SIMPLE_TYPE_MSCHAP,
-                                          TRUE,
-                                          method->is_editor,
-                                          secrets_only);
+                                          simple_flags);
        gtk_list_store_append (auth_model, &iter);
        gtk_list_store_set (auth_model, &iter,
                            I_NAME_COLUMN, _("MSCHAP"),
@@ -274,8 +279,7 @@ inner_auth_combo_init (EAPMethodTTLS *method,
        em_mschap_v2 = eap_method_simple_new (method->sec_parent,
                                              connection,
                                              EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2,
-                                             TRUE,
-                                             method->is_editor, secrets_only);
+                                             simple_flags);
        gtk_list_store_append (auth_model, &iter);
        gtk_list_store_set (auth_model, &iter,
                            I_NAME_COLUMN, _("MSCHAPv2"),
@@ -290,9 +294,7 @@ inner_auth_combo_init (EAPMethodTTLS *method,
        em_chap = eap_method_simple_new (method->sec_parent,
                                         connection,
                                         EAP_METHOD_SIMPLE_TYPE_CHAP,
-                                        TRUE,
-                                        method->is_editor,
-                                        secrets_only);
+                                        simple_flags);
        gtk_list_store_append (auth_model, &iter);
        gtk_list_store_set (auth_model, &iter,
                            I_NAME_COLUMN, _("CHAP"),
@@ -304,6 +306,36 @@ inner_auth_combo_init (EAPMethodTTLS *method,
        if (phase2_auth && !strcasecmp (phase2_auth, "chap"))
                active = 3;
 
+       em_md5 = eap_method_simple_new (method->sec_parent,
+                                       connection,
+                                       EAP_METHOD_SIMPLE_TYPE_MD5,
+                                       simple_flags);
+       gtk_list_store_append (auth_model, &iter);
+       gtk_list_store_set (auth_model, &iter,
+                           I_NAME_COLUMN, _("MD5"),
+                           I_METHOD_COLUMN, em_md5,
+                           -1);
+       eap_method_unref (EAP_METHOD (em_md5));
+
+       /* Check for defaulting to MD5 */
+       if (phase2_auth && !strcasecmp (phase2_auth, "md5"))
+               active = 4;
+
+       em_gtc = eap_method_simple_new (method->sec_parent,
+                                       connection,
+                                       EAP_METHOD_SIMPLE_TYPE_GTC,
+                                       simple_flags);
+       gtk_list_store_append (auth_model, &iter);
+       gtk_list_store_set (auth_model, &iter,
+                           I_NAME_COLUMN, _("GTC"),
+                           I_METHOD_COLUMN, em_gtc,
+                           -1);
+       eap_method_unref (EAP_METHOD (em_gtc));
+
+       /* Check for defaulting to GTC */
+       if (phase2_auth && !strcasecmp (phase2_auth, "gtc"))
+               active = 5;
+
        combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo"));
        g_assert (combo);
 
diff --git a/src/wireless-security/wireless-security.c b/src/wireless-security/wireless-security.c
index d64fe1d..7e009d5 100644
--- a/src/wireless-security/wireless-security.c
+++ b/src/wireless-security/wireless-security.c
@@ -382,6 +382,7 @@ ws_802_1x_auth_combo_init (WirelessSecurity *sec,
        const char *default_method = NULL, *ctype = NULL;
        int active = -1, item = 0;
        gboolean wired = FALSE;
+       EAPMethodSimpleFlags simple_flags = EAP_METHOD_SIMPLE_FLAG_NONE;
 
        /* Grab the default EAP method out of the security object */
        if (connection) {
@@ -405,13 +406,13 @@ ws_802_1x_auth_combo_init (WirelessSecurity *sec,
 
        auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ());
 
+       if (is_editor)
+               simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR;
+       if (secrets_only)
+               simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY;
+
        if (wired) {
-               em_md5 = eap_method_simple_new (sec,
-                                               connection,
-                                               EAP_METHOD_SIMPLE_TYPE_MD5,
-                                               FALSE,
-                                               is_editor,
-                                               secrets_only);
+               em_md5 = eap_method_simple_new (sec, connection, EAP_METHOD_SIMPLE_TYPE_MD5, simple_flags);
                gtk_list_store_append (auth_model, &iter);
                gtk_list_store_set (auth_model, &iter,
                                        AUTH_NAME_COLUMN, _("MD5"),
@@ -447,8 +448,7 @@ ws_802_1x_auth_combo_init (WirelessSecurity *sec,
                item++;
        }
 
-       em_pwd = eap_method_simple_new (sec, connection, EAP_METHOD_SIMPLE_TYPE_PWD,
-                                       FALSE, is_editor, secrets_only);
+       em_pwd = eap_method_simple_new (sec, connection, EAP_METHOD_SIMPLE_TYPE_PWD, simple_flags);
        gtk_list_store_append (auth_model, &iter);
        gtk_list_store_set (auth_model, &iter,
                            AUTH_NAME_COLUMN, _("PWD"),


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