wpa_gui-qt4: Added support for configuring Phase 2 method
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 1 Oct 2008 13:43:36 +0000 (16:43 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 1 Oct 2008 13:43:36 +0000 (16:43 +0300)
wpa_supplicant/ChangeLog
wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
wpa_supplicant/wpa_gui-qt4/networkconfig.h
wpa_supplicant/wpa_gui-qt4/networkconfig.ui

index 447d947..3e64d81 100644 (file)
@@ -8,6 +8,8 @@ ChangeLog for wpa_supplicant
          (IEEE 802.11w)
        * fixed FT (IEEE 802.11r) authentication after a failed association to
          use correct FTIE
+       * added support for configuring Phase 2 (inner/tunneled) authentication
+         method with wpa_gui-qt4
 
 2008-08-10 - v0.6.4
        * added support for EAP Sequences in EAP-FAST Phase 2
index 813c5ed..44d70d4 100644 (file)
@@ -41,6 +41,8 @@ NetworkConfig::NetworkConfig(QWidget *parent, const char *, bool, Qt::WFlags)
        connect(encrSelect, SIGNAL(activated(const QString &)), this,
                SLOT(encrChanged(const QString &)));
        connect(removeButton, SIGNAL(clicked()), this, SLOT(removeNetwork()));
+       connect(eapSelect, SIGNAL(activated(int)), this,
+               SLOT(eapChanged(int)));
 
        wpagui = NULL;
        new_network = false;
@@ -107,6 +109,9 @@ void NetworkConfig::authChanged(int sel)
        identityEdit->setEnabled(eap);
        passwordEdit->setEnabled(eap);
        cacertEdit->setEnabled(eap);
+       phase2Select->setEnabled(eap);
+       if (eap)
+               eapChanged(eapSelect->currentIndex());
 
        while (encrSelect->count())
                encrSelect->removeItem(0);
@@ -126,6 +131,48 @@ void NetworkConfig::authChanged(int sel)
 }
 
 
+void NetworkConfig::eapChanged(int sel)
+{
+       QString prev_val = phase2Select->currentText();
+       while (phase2Select->count())
+               phase2Select->removeItem(0);
+
+       QStringList inner;
+       inner << "PEAP" << "TTLS" << "FAST";
+       if (!inner.contains(eapSelect->itemText(sel)))
+               return;
+
+       phase2Select->addItem("[ any ]");
+
+       /* Add special cases based on outer method */
+       if (eapSelect->currentText().compare("TTLS") == 0) {
+               phase2Select->addItem("PAP");
+               phase2Select->addItem("CHAP");
+               phase2Select->addItem("MSCHAP");
+               phase2Select->addItem("MSCHAPv2");
+       } else if (eapSelect->currentText().compare("FAST") == 0)
+               phase2Select->addItem("GTC(auth) + MSCHAPv2(prov)");
+
+       /* Add all enabled EAP methods that can be used in the tunnel */
+       int i;
+       QStringList allowed;
+       allowed << "MSCHAPV2" << "MD5" << "GTC" << "TLS" << "OTP" << "SIM"
+               << "AKA";
+       for (i = 0; i < eapSelect->count(); i++) {
+               if (allowed.contains(eapSelect->itemText(i))) {
+                       phase2Select->addItem("EAP-" + eapSelect->itemText(i));
+               }
+       }
+
+       for (i = 0; i < phase2Select->count(); i++) {
+               if (phase2Select->itemText(i).compare(prev_val) == 0) {
+                       phase2Select->setCurrentIndex(i);
+                       break;
+               }
+       }
+}
+
+
 void NetworkConfig::addNetwork()
 {
        char reply[10], cmd[256];
@@ -237,6 +284,37 @@ void NetworkConfig::addNetwork()
                if (strcmp(eap, "SIM") == 0 || strcmp(eap, "AKA") == 0)
                        setNetworkParam(id, "pcsc", "", true);
        }
+       if (phase2Select->isEnabled()) {
+               QString eap = eapSelect->currentText();
+               QString inner = phase2Select->currentText();
+               char phase2[32];
+               phase2[0] = '\0';
+               if (eap.compare("PEAP") == 0) {
+                       if (inner.startsWith("EAP-"))
+                               snprintf(phase2, sizeof(phase2), "auth=%s",
+                                        inner.right(inner.size() - 4).
+                                        toAscii().constData());
+               } else if (eap.compare("TTLS") == 0) {
+                       if (inner.startsWith("EAP-"))
+                               snprintf(phase2, sizeof(phase2), "autheap=%s",
+                                        inner.right(inner.size() - 4).
+                                        toAscii().constData());
+                       else
+                               snprintf(phase2, sizeof(phase2), "auth=%s",
+                                        inner.toAscii().constData());
+               } else if (eap.compare("FAST") == 0) {
+                       if (inner.startsWith("EAP-"))
+                               snprintf(phase2, sizeof(phase2), "auth=%s",
+                                        inner.right(inner.size() - 4).
+                                        toAscii().constData());
+                       else if (inner.compare("GTC(auth) + MSCHAPv2(prov)") ==
+                                0) {
+                               snprintf(phase2, sizeof(phase2),
+                                        "auth=GTC MSCHAPV2");
+                       }
+               }
+               setNetworkParam(id, "phase2", phase2, true);
+       }
        if (identityEdit->isEnabled())
                setNetworkParam(id, "identity",
                                identityEdit->text().toAscii().constData(),
@@ -484,6 +562,7 @@ void NetworkConfig::paramsFromConfig(int network_id)
                cacertEdit->setText(reply + 1);
        }
 
+       enum { NO_INNER, PEAP_INNER, TTLS_INNER, FAST_INNER } eap = NO_INNER;
        snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
        reply_len = sizeof(reply) - 1;
        if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
@@ -492,11 +571,71 @@ void NetworkConfig::paramsFromConfig(int network_id)
                for (i = 0; i < eapSelect->count(); i++) {
                        if (eapSelect->itemText(i).compare(reply) == 0) {
                                eapSelect->setCurrentIndex(i);
+                               if (strcmp(reply, "PEAP") == 0)
+                                       eap = PEAP_INNER;
+                               else if (strcmp(reply, "TTLS") == 0)
+                                       eap = TTLS_INNER;
+                               else if (strcmp(reply, "FAST") == 0)
+                                       eap = FAST_INNER;
                                break;
                        }
                }
        }
 
+       if (eap != NO_INNER) {
+               snprintf(cmd, sizeof(cmd), "GET_NETWORK %d phase2",
+                        network_id);
+               reply_len = sizeof(reply) - 1;
+               if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
+                   reply_len >= 1) {
+                       reply[reply_len] = '\0';
+                       eapChanged(eapSelect->currentIndex());
+               } else
+                       eap = NO_INNER;
+       }
+
+       char *val;
+       val = reply + 1;
+       while (*(val + 1))
+               val++;
+       if (*val == '"')
+               *val = '\0';
+
+       switch (eap) {
+       case PEAP_INNER:
+               if (strncmp(reply, "\"auth=", 6))
+                       break;
+               val = reply + 2;
+               memcpy(val, "EAP-", 4);
+               break;
+       case TTLS_INNER:
+               if (strncmp(reply, "\"autheap=", 9) == 0) {
+                       val = reply + 5;
+                       memcpy(val, "EAP-", 4);
+               } else if (strncmp(reply, "\"auth=", 6) == 0)
+                       val = reply + 6;
+               break;
+       case FAST_INNER:
+               if (strncmp(reply, "\"auth=", 6))
+                       break;
+               if (strcmp(reply + 6, "GTC MSCHAPV2") == 0) {
+                       val = "GTC(auth) + MSCHAPv2(prov)";
+                       break;
+               }
+               val = reply + 2;
+               memcpy(val, "EAP-", 4);
+               break;
+       case NO_INNER:
+               break;
+       }
+
+       for (i = 0; i < phase2Select->count(); i++) {
+               if (phase2Select->itemText(i).compare(val) == 0) {
+                       phase2Select->setCurrentIndex(i);
+                       break;
+               }
+       }
+
        for (i = 0; i < 4; i++) {
                QLineEdit *wepEdit;
                switch (i) {
index 140f5d7..d37eed3 100644 (file)
@@ -42,6 +42,7 @@ public slots:
        virtual void encrChanged(const QString &sel);
        virtual void writeWepKey(int network_id, QLineEdit *edit, int id);
        virtual void removeNetwork();
+       virtual void eapChanged(int sel);
 
 protected slots:
        virtual void languageChange();
index 8ba1c3f..bd5dd75 100644 (file)
@@ -6,7 +6,7 @@
     <x>0</x>
     <y>0</y>
     <width>410</width>
-    <height>510</height>
+    <height>534</height>
    </rect>
   </property>
   <property name="windowTitle" >
            </property>
           </widget>
          </item>
+         <item row="1" column="0" >
+          <widget class="QLabel" name="phase2Label" >
+           <property name="text" >
+            <string>Inner auth</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1" >
+          <widget class="QComboBox" name="phase2Select" >
+           <property name="enabled" >
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
         </layout>
        </widget>
       </item>
   <tabstop>wep3Edit</tabstop>
   <tabstop>idstrEdit</tabstop>
   <tabstop>prioritySpinBox</tabstop>
+  <tabstop>phase2Select</tabstop>
   <tabstop>addButton</tabstop>
   <tabstop>removeButton</tabstop>
   <tabstop>cancelButton</tabstop>