wpa_gui-qt4: Dynamically update associated STAs in peer dialog
[mech_eap.git] / wpa_supplicant / wpa_gui-qt4 / networkconfig.cpp
1 /*
2  * wpa_gui - NetworkConfig class
3  * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include <cstdio>
16 #include <QMessageBox>
17
18 #include "networkconfig.h"
19 #include "wpagui.h"
20
21 enum {
22         AUTH_NONE_OPEN,
23         AUTH_NONE_WEP,
24         AUTH_NONE_WEP_SHARED,
25         AUTH_IEEE8021X,
26         AUTH_WPA_PSK,
27         AUTH_WPA_EAP,
28         AUTH_WPA2_PSK,
29         AUTH_WPA2_EAP
30 };
31
32 #define WPA_GUI_KEY_DATA "[key is configured]"
33
34
35 NetworkConfig::NetworkConfig(QWidget *parent, const char *, bool, Qt::WFlags)
36         : QDialog(parent)
37 {
38         setupUi(this);
39
40         encrSelect->setEnabled(false);
41         connect(authSelect, SIGNAL(activated(int)), this,
42                 SLOT(authChanged(int)));
43         connect(cancelButton, SIGNAL(clicked()), this, SLOT(close()));
44         connect(addButton, SIGNAL(clicked()), this, SLOT(addNetwork()));
45         connect(encrSelect, SIGNAL(activated(const QString &)), this,
46                 SLOT(encrChanged(const QString &)));
47         connect(removeButton, SIGNAL(clicked()), this, SLOT(removeNetwork()));
48         connect(eapSelect, SIGNAL(activated(int)), this,
49                 SLOT(eapChanged(int)));
50         connect(useWpsButton, SIGNAL(clicked()), this, SLOT(useWps()));
51
52         wpagui = NULL;
53         new_network = false;
54 }
55
56
57 NetworkConfig::~NetworkConfig()
58 {
59 }
60
61
62 void NetworkConfig::languageChange()
63 {
64         retranslateUi(this);
65 }
66
67
68 void NetworkConfig::paramsFromScanResults(QTreeWidgetItem *sel)
69 {
70         new_network = true;
71
72         /* SSID BSSID frequency signal flags */
73         setWindowTitle(sel->text(0));
74         ssidEdit->setText(sel->text(0));
75
76         QString flags = sel->text(4);
77         int auth, encr = 0;
78         if (flags.indexOf("[WPA2-EAP") >= 0)
79                 auth = AUTH_WPA2_EAP;
80         else if (flags.indexOf("[WPA-EAP") >= 0)
81                 auth = AUTH_WPA_EAP;
82         else if (flags.indexOf("[WPA2-PSK") >= 0)
83                 auth = AUTH_WPA2_PSK;
84         else if (flags.indexOf("[WPA-PSK") >= 0)
85                 auth = AUTH_WPA_PSK;
86         else
87                 auth = AUTH_NONE_OPEN;
88
89         if (flags.indexOf("-CCMP") >= 0)
90                 encr = 1;
91         else if (flags.indexOf("-TKIP") >= 0)
92                 encr = 0;
93         else if (flags.indexOf("WEP") >= 0) {
94                 encr = 1;
95                 if (auth == AUTH_NONE_OPEN)
96                         auth = AUTH_NONE_WEP;
97         } else
98                 encr = 0;
99
100         authSelect->setCurrentIndex(auth);
101         authChanged(auth);
102         encrSelect->setCurrentIndex(encr);
103
104         wepEnabled(auth == AUTH_NONE_WEP);
105
106         getEapCapa();
107
108         if (flags.indexOf("[WPS") >= 0)
109                 useWpsButton->setEnabled(true);
110         bssid = sel->text(1);
111 }
112
113
114 void NetworkConfig::authChanged(int sel)
115 {
116         encrSelect->setEnabled(sel != AUTH_NONE_OPEN && sel != AUTH_NONE_WEP &&
117                                sel != AUTH_NONE_WEP_SHARED);
118         pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK);
119         bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP ||
120                 sel == AUTH_WPA2_EAP;
121         eapSelect->setEnabled(eap);
122         identityEdit->setEnabled(eap);
123         passwordEdit->setEnabled(eap);
124         cacertEdit->setEnabled(eap);
125         phase2Select->setEnabled(eap);
126         if (eap)
127                 eapChanged(eapSelect->currentIndex());
128
129         while (encrSelect->count())
130                 encrSelect->removeItem(0);
131
132         if (sel == AUTH_NONE_OPEN || sel == AUTH_NONE_WEP ||
133             sel == AUTH_NONE_WEP_SHARED || sel == AUTH_IEEE8021X) {
134                 encrSelect->addItem("None");
135                 encrSelect->addItem("WEP");
136                 encrSelect->setCurrentIndex(sel == AUTH_NONE_OPEN ? 0 : 1);
137         } else {
138                 encrSelect->addItem("TKIP");
139                 encrSelect->addItem("CCMP");
140                 encrSelect->setCurrentIndex((sel == AUTH_WPA2_PSK ||
141                                              sel == AUTH_WPA2_EAP) ? 1 : 0);
142         }
143
144         wepEnabled(sel == AUTH_NONE_WEP || sel == AUTH_NONE_WEP_SHARED);
145 }
146
147
148 void NetworkConfig::eapChanged(int sel)
149 {
150         QString prev_val = phase2Select->currentText();
151         while (phase2Select->count())
152                 phase2Select->removeItem(0);
153
154         QStringList inner;
155         inner << "PEAP" << "TTLS" << "FAST";
156         if (!inner.contains(eapSelect->itemText(sel)))
157                 return;
158
159         phase2Select->addItem("[ any ]");
160
161         /* Add special cases based on outer method */
162         if (eapSelect->currentText().compare("TTLS") == 0) {
163                 phase2Select->addItem("PAP");
164                 phase2Select->addItem("CHAP");
165                 phase2Select->addItem("MSCHAP");
166                 phase2Select->addItem("MSCHAPv2");
167         } else if (eapSelect->currentText().compare("FAST") == 0)
168                 phase2Select->addItem("GTC(auth) + MSCHAPv2(prov)");
169
170         /* Add all enabled EAP methods that can be used in the tunnel */
171         int i;
172         QStringList allowed;
173         allowed << "MSCHAPV2" << "MD5" << "GTC" << "TLS" << "OTP" << "SIM"
174                 << "AKA";
175         for (i = 0; i < eapSelect->count(); i++) {
176                 if (allowed.contains(eapSelect->itemText(i))) {
177                         phase2Select->addItem("EAP-" + eapSelect->itemText(i));
178                 }
179         }
180
181         for (i = 0; i < phase2Select->count(); i++) {
182                 if (phase2Select->itemText(i).compare(prev_val) == 0) {
183                         phase2Select->setCurrentIndex(i);
184                         break;
185                 }
186         }
187 }
188
189
190 void NetworkConfig::addNetwork()
191 {
192         char reply[10], cmd[256];
193         size_t reply_len;
194         int id;
195         int psklen = pskEdit->text().length();
196         int auth = authSelect->currentIndex();
197
198         if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) {
199                 if (psklen < 8 || psklen > 64) {
200                         QMessageBox::warning(this, "WPA Pre-Shared Key Error",
201                                              "WPA-PSK requires a passphrase "
202                                              "of 8 to 63 characters\n"
203                                              "or 64 hex digit PSK");
204                         pskEdit->setFocus();
205                         return;
206                 }
207         }
208
209         if (idstrEdit->isEnabled() && !idstrEdit->text().isEmpty()) {
210                 QRegExp rx("^(\\w|-)+$");
211                 if (rx.indexIn(idstrEdit->text()) < 0) {
212                         QMessageBox::warning(this, "Network ID Error",
213                                              "Network ID String contains "
214                                              "non-word characters.\n"
215                                              "It must be a simple string, "
216                                              "without spaces, containing\n"
217                                              "only characters in this range: "
218                                              "[A-Za-z0-9_-]\n");
219                         idstrEdit->setFocus();
220                         return;
221                 }
222         }
223
224         if (wpagui == NULL)
225                 return;
226
227         memset(reply, 0, sizeof(reply));
228         reply_len = sizeof(reply) - 1;
229
230         if (new_network) {
231                 wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len);
232                 if (reply[0] == 'F') {
233                         QMessageBox::warning(this, "wpa_gui", "Failed to add "
234                                              "network to wpa_supplicant\n"
235                                              "configuration.");
236                         return;
237                 }
238                 id = atoi(reply);
239         } else
240                 id = edit_network_id;
241
242         setNetworkParam(id, "ssid", ssidEdit->text().toAscii().constData(),
243                         true);
244
245         const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
246         switch (auth) {
247         case AUTH_NONE_OPEN:
248         case AUTH_NONE_WEP:
249         case AUTH_NONE_WEP_SHARED:
250                 key_mgmt = "NONE";
251                 break;
252         case AUTH_IEEE8021X:
253                 key_mgmt = "IEEE8021X";
254                 break;
255         case AUTH_WPA_PSK:
256                 key_mgmt = "WPA-PSK";
257                 proto = "WPA";
258                 break;
259         case AUTH_WPA_EAP:
260                 key_mgmt = "WPA-EAP";
261                 proto = "WPA";
262                 break;
263         case AUTH_WPA2_PSK:
264                 key_mgmt = "WPA-PSK";
265                 proto = "WPA2";
266                 break;
267         case AUTH_WPA2_EAP:
268                 key_mgmt = "WPA-EAP";
269                 proto = "WPA2";
270                 break;
271         }
272
273         if (auth == AUTH_NONE_WEP_SHARED)
274                 setNetworkParam(id, "auth_alg", "SHARED", false);
275         else
276                 setNetworkParam(id, "auth_alg", "OPEN", false);
277
278         if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
279             auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
280                 int encr = encrSelect->currentIndex();
281                 if (encr == 0)
282                         pairwise = "TKIP";
283                 else
284                         pairwise = "CCMP";
285         }
286
287         if (proto)
288                 setNetworkParam(id, "proto", proto, false);
289         if (key_mgmt)
290                 setNetworkParam(id, "key_mgmt", key_mgmt, false);
291         if (pairwise) {
292                 setNetworkParam(id, "pairwise", pairwise, false);
293                 setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
294         }
295         if (pskEdit->isEnabled() &&
296             strcmp(pskEdit->text().toAscii().constData(),
297                    WPA_GUI_KEY_DATA) != 0)
298                 setNetworkParam(id, "psk",
299                                 pskEdit->text().toAscii().constData(),
300                                 psklen != 64);
301         if (eapSelect->isEnabled()) {
302                 const char *eap =
303                         eapSelect->currentText().toAscii().constData();
304                 setNetworkParam(id, "eap", eap, false);
305                 if (strcmp(eap, "SIM") == 0 || strcmp(eap, "AKA") == 0)
306                         setNetworkParam(id, "pcsc", "", true);
307                 else
308                         setNetworkParam(id, "pcsc", "NULL", false);
309         }
310         if (phase2Select->isEnabled()) {
311                 QString eap = eapSelect->currentText();
312                 QString inner = phase2Select->currentText();
313                 char phase2[32];
314                 phase2[0] = '\0';
315                 if (eap.compare("PEAP") == 0) {
316                         if (inner.startsWith("EAP-"))
317                                 snprintf(phase2, sizeof(phase2), "auth=%s",
318                                          inner.right(inner.size() - 4).
319                                          toAscii().constData());
320                 } else if (eap.compare("TTLS") == 0) {
321                         if (inner.startsWith("EAP-"))
322                                 snprintf(phase2, sizeof(phase2), "autheap=%s",
323                                          inner.right(inner.size() - 4).
324                                          toAscii().constData());
325                         else
326                                 snprintf(phase2, sizeof(phase2), "auth=%s",
327                                          inner.toAscii().constData());
328                 } else if (eap.compare("FAST") == 0) {
329                         const char *provisioning = NULL;
330                         if (inner.startsWith("EAP-")) {
331                                 snprintf(phase2, sizeof(phase2), "auth=%s",
332                                          inner.right(inner.size() - 4).
333                                          toAscii().constData());
334                                 provisioning = "fast_provisioning=2";
335                         } else if (inner.compare("GTC(auth) + MSCHAPv2(prov)")
336                                    == 0) {
337                                 snprintf(phase2, sizeof(phase2),
338                                          "auth=GTC auth=MSCHAPV2");
339                                 provisioning = "fast_provisioning=1";
340                         } else
341                                 provisioning = "fast_provisioning=3";
342                         if (provisioning) {
343                                 char blob[32];
344                                 setNetworkParam(id, "phase1", provisioning,
345                                                 true);
346                                 snprintf(blob, sizeof(blob),
347                                          "blob://fast-pac-%d", id);
348                                 setNetworkParam(id, "pac_file", blob, true);
349                         }
350                 }
351                 if (phase2[0])
352                         setNetworkParam(id, "phase2", phase2, true);
353                 else
354                         setNetworkParam(id, "phase2", "NULL", false);
355         } else
356                 setNetworkParam(id, "phase2", "NULL", false);
357         if (identityEdit->isEnabled() && identityEdit->text().length() > 0)
358                 setNetworkParam(id, "identity",
359                                 identityEdit->text().toAscii().constData(),
360                                 true);
361         else
362                 setNetworkParam(id, "identity", "NULL", false);
363         if (passwordEdit->isEnabled() && passwordEdit->text().length() > 0 &&
364             strcmp(passwordEdit->text().toAscii().constData(),
365                    WPA_GUI_KEY_DATA) != 0)
366                 setNetworkParam(id, "password",
367                                 passwordEdit->text().toAscii().constData(),
368                                 true);
369         else if (passwordEdit->text().length() == 0)
370                 setNetworkParam(id, "password", "NULL", false);
371         if (cacertEdit->isEnabled() && cacertEdit->text().length() > 0)
372                 setNetworkParam(id, "ca_cert",
373                                 cacertEdit->text().toAscii().constData(),
374                                 true);
375         else
376                 setNetworkParam(id, "ca_cert", "NULL", false);
377         writeWepKey(id, wep0Edit, 0);
378         writeWepKey(id, wep1Edit, 1);
379         writeWepKey(id, wep2Edit, 2);
380         writeWepKey(id, wep3Edit, 3);
381
382         if (wep0Radio->isEnabled() && wep0Radio->isChecked())
383                 setNetworkParam(id, "wep_tx_keyidx", "0", false);
384         else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
385                 setNetworkParam(id, "wep_tx_keyidx", "1", false);
386         else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
387                 setNetworkParam(id, "wep_tx_keyidx", "2", false);
388         else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
389                 setNetworkParam(id, "wep_tx_keyidx", "3", false);
390
391         if (idstrEdit->isEnabled() && idstrEdit->text().length() > 0)
392                 setNetworkParam(id, "id_str",
393                                 idstrEdit->text().toAscii().constData(),
394                                 true);
395         else
396                 setNetworkParam(id, "id_str", "NULL", false);
397
398         if (prioritySpinBox->isEnabled()) {
399                 QString prio;
400                 prio = prio.setNum(prioritySpinBox->value());
401                 setNetworkParam(id, "priority", prio.toAscii().constData(),
402                                 false);
403         }
404
405         snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
406         reply_len = sizeof(reply);
407         wpagui->ctrlRequest(cmd, reply, &reply_len);
408         if (strncmp(reply, "OK", 2) != 0) {
409                 QMessageBox::warning(this, "wpa_gui", "Failed to enable "
410                                      "network in wpa_supplicant\n"
411                                      "configuration.");
412                 /* Network was added, so continue anyway */
413         }
414         wpagui->triggerUpdate();
415         wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
416
417         close();
418 }
419
420
421 void NetworkConfig::setWpaGui(WpaGui *_wpagui)
422 {
423         wpagui = _wpagui;
424 }
425
426
427 int NetworkConfig::setNetworkParam(int id, const char *field,
428                                    const char *value, bool quote)
429 {
430         char reply[10], cmd[256];
431         size_t reply_len;
432         snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
433                  id, field, quote ? "\"" : "", value, quote ? "\"" : "");
434         reply_len = sizeof(reply);
435         wpagui->ctrlRequest(cmd, reply, &reply_len);
436         return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
437 }
438
439
440 void NetworkConfig::encrChanged(const QString &)
441 {
442 }
443
444
445 void NetworkConfig::wepEnabled(bool enabled)
446 {
447         wep0Edit->setEnabled(enabled);
448         wep1Edit->setEnabled(enabled);
449         wep2Edit->setEnabled(enabled);
450         wep3Edit->setEnabled(enabled);
451         wep0Radio->setEnabled(enabled);
452         wep1Radio->setEnabled(enabled);
453         wep2Radio->setEnabled(enabled);
454         wep3Radio->setEnabled(enabled);
455 }
456
457
458 void NetworkConfig::writeWepKey(int network_id, QLineEdit *edit, int id)
459 {
460         char buf[10];
461         bool hex;
462         const char *txt, *pos;
463         size_t len;
464
465         if (!edit->isEnabled() || edit->text().isEmpty())
466                 return;
467
468         /*
469          * Assume hex key if only hex characters are present and length matches
470          * with 40, 104, or 128-bit key
471          */
472         txt = edit->text().toAscii().constData();
473         if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
474                 return;
475         len = strlen(txt);
476         if (len == 0)
477                 return;
478         pos = txt;
479         hex = true;
480         while (*pos) {
481                 if (!((*pos >= '0' && *pos <= '9') ||
482                       (*pos >= 'a' && *pos <= 'f') ||
483                       (*pos >= 'A' && *pos <= 'F'))) {
484                         hex = false;
485                         break;
486                 }
487                 pos++;
488         }
489         if (hex && len != 10 && len != 26 && len != 32)
490                 hex = false;
491         snprintf(buf, sizeof(buf), "wep_key%d", id);
492         setNetworkParam(network_id, buf, txt, !hex);
493 }
494
495
496 static int key_value_isset(const char *reply, size_t reply_len)
497 {
498     return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
499 }
500
501
502 void NetworkConfig::paramsFromConfig(int network_id)
503 {
504         int i, res;
505
506         edit_network_id = network_id;
507         getEapCapa();
508
509         char reply[1024], cmd[256], *pos;
510         size_t reply_len;
511
512         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
513         reply_len = sizeof(reply) - 1;
514         if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
515             reply_len >= 2 && reply[0] == '"') {
516                 reply[reply_len] = '\0';
517                 pos = strchr(reply + 1, '"');
518                 if (pos)
519                         *pos = '\0';
520                 ssidEdit->setText(reply + 1);
521         }
522
523         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
524         reply_len = sizeof(reply) - 1;
525         int wpa = 0;
526         if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
527                 reply[reply_len] = '\0';
528                 if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
529                         wpa = 2;
530                 else if (strstr(reply, "WPA"))
531                         wpa = 1;
532         }
533
534         int auth = AUTH_NONE_OPEN, encr = 0;
535         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
536         reply_len = sizeof(reply) - 1;
537         if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
538                 reply[reply_len] = '\0';
539                 if (strstr(reply, "WPA-EAP"))
540                         auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
541                 else if (strstr(reply, "WPA-PSK"))
542                         auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
543                 else if (strstr(reply, "IEEE8021X")) {
544                         auth = AUTH_IEEE8021X;
545                         encr = 1;
546                 }
547         }
548
549         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
550         reply_len = sizeof(reply) - 1;
551         if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
552                 reply[reply_len] = '\0';
553                 if (strstr(reply, "CCMP") && auth != AUTH_NONE_OPEN &&
554                     auth != AUTH_NONE_WEP && auth != AUTH_NONE_WEP_SHARED)
555                         encr = 1;
556                 else if (strstr(reply, "TKIP"))
557                         encr = 0;
558                 else if (strstr(reply, "WEP"))
559                         encr = 1;
560                 else
561                         encr = 0;
562         }
563
564         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
565         reply_len = sizeof(reply) - 1;
566         res = wpagui->ctrlRequest(cmd, reply, &reply_len);
567         if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
568                 reply[reply_len] = '\0';
569                 pos = strchr(reply + 1, '"');
570                 if (pos)
571                         *pos = '\0';
572                 pskEdit->setText(reply + 1);
573         } else if (res >= 0 && key_value_isset(reply, reply_len)) {
574                 pskEdit->setText(WPA_GUI_KEY_DATA);
575         }
576
577         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
578         reply_len = sizeof(reply) - 1;
579         if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
580             reply_len >= 2 && reply[0] == '"') {
581                 reply[reply_len] = '\0';
582                 pos = strchr(reply + 1, '"');
583                 if (pos)
584                         *pos = '\0';
585                 identityEdit->setText(reply + 1);
586         }
587
588         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
589         reply_len = sizeof(reply) - 1;
590         res = wpagui->ctrlRequest(cmd, reply, &reply_len);
591         if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
592                 reply[reply_len] = '\0';
593                 pos = strchr(reply + 1, '"');
594                 if (pos)
595                         *pos = '\0';
596                 passwordEdit->setText(reply + 1);
597         } else if (res >= 0 && key_value_isset(reply, reply_len)) {
598                 passwordEdit->setText(WPA_GUI_KEY_DATA);
599         }
600
601         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
602         reply_len = sizeof(reply) - 1;
603         if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
604             reply_len >= 2 && reply[0] == '"') {
605                 reply[reply_len] = '\0';
606                 pos = strchr(reply + 1, '"');
607                 if (pos)
608                         *pos = '\0';
609                 cacertEdit->setText(reply + 1);
610         }
611
612         enum { NO_INNER, PEAP_INNER, TTLS_INNER, FAST_INNER } eap = NO_INNER;
613         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
614         reply_len = sizeof(reply) - 1;
615         if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
616             reply_len >= 1) {
617                 reply[reply_len] = '\0';
618                 for (i = 0; i < eapSelect->count(); i++) {
619                         if (eapSelect->itemText(i).compare(reply) == 0) {
620                                 eapSelect->setCurrentIndex(i);
621                                 if (strcmp(reply, "PEAP") == 0)
622                                         eap = PEAP_INNER;
623                                 else if (strcmp(reply, "TTLS") == 0)
624                                         eap = TTLS_INNER;
625                                 else if (strcmp(reply, "FAST") == 0)
626                                         eap = FAST_INNER;
627                                 break;
628                         }
629                 }
630         }
631
632         if (eap != NO_INNER) {
633                 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d phase2",
634                          network_id);
635                 reply_len = sizeof(reply) - 1;
636                 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
637                     reply_len >= 1) {
638                         reply[reply_len] = '\0';
639                         eapChanged(eapSelect->currentIndex());
640                 } else
641                         eap = NO_INNER;
642         }
643
644         char *val;
645         val = reply + 1;
646         while (*(val + 1))
647                 val++;
648         if (*val == '"')
649                 *val = '\0';
650
651         switch (eap) {
652         case PEAP_INNER:
653                 if (strncmp(reply, "\"auth=", 6))
654                         break;
655                 val = reply + 2;
656                 memcpy(val, "EAP-", 4);
657                 break;
658         case TTLS_INNER:
659                 if (strncmp(reply, "\"autheap=", 9) == 0) {
660                         val = reply + 5;
661                         memcpy(val, "EAP-", 4);
662                 } else if (strncmp(reply, "\"auth=", 6) == 0)
663                         val = reply + 6;
664                 break;
665         case FAST_INNER:
666                 if (strncmp(reply, "\"auth=", 6))
667                         break;
668                 if (strcmp(reply + 6, "GTC auth=MSCHAPV2") == 0) {
669                         val = (char *) "GTC(auth) + MSCHAPv2(prov)";
670                         break;
671                 }
672                 val = reply + 2;
673                 memcpy(val, "EAP-", 4);
674                 break;
675         case NO_INNER:
676                 break;
677         }
678
679         for (i = 0; i < phase2Select->count(); i++) {
680                 if (phase2Select->itemText(i).compare(val) == 0) {
681                         phase2Select->setCurrentIndex(i);
682                         break;
683                 }
684         }
685
686         for (i = 0; i < 4; i++) {
687                 QLineEdit *wepEdit;
688                 switch (i) {
689                 default:
690                 case 0:
691                         wepEdit = wep0Edit;
692                         break;
693                 case 1:
694                         wepEdit = wep1Edit;
695                         break;
696                 case 2:
697                         wepEdit = wep2Edit;
698                         break;
699                 case 3:
700                         wepEdit = wep3Edit;
701                         break;
702                 }
703                 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d",
704                          network_id, i);
705                 reply_len = sizeof(reply) - 1;
706                 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
707                 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
708                         reply[reply_len] = '\0';
709                         pos = strchr(reply + 1, '"');
710                         if (pos)
711                                 *pos = '\0';
712                         if (auth == AUTH_NONE_OPEN || auth == AUTH_IEEE8021X) {
713                                 if (auth == AUTH_NONE_OPEN)
714                                         auth = AUTH_NONE_WEP;
715                                 encr = 1;
716                         }
717
718                         wepEdit->setText(reply + 1);
719                 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
720                         if (auth == AUTH_NONE_OPEN || auth == AUTH_IEEE8021X) {
721                                 if (auth == AUTH_NONE_OPEN)
722                                         auth = AUTH_NONE_WEP;
723                                 encr = 1;
724                         }
725                         wepEdit->setText(WPA_GUI_KEY_DATA);
726                 }
727         }
728
729         if (auth == AUTH_NONE_WEP) {
730                 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d auth_alg",
731                          network_id);
732                 reply_len = sizeof(reply) - 1;
733                 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
734                         reply[reply_len] = '\0';
735                         if (strcmp(reply, "SHARED") == 0)
736                                 auth = AUTH_NONE_WEP_SHARED;
737                 }
738         }
739
740         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
741         reply_len = sizeof(reply) - 1;
742         if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
743         {
744                 reply[reply_len] = '\0';
745                 switch (atoi(reply)) {
746                 case 0:
747                         wep0Radio->setChecked(true);
748                         break;
749                 case 1:
750                         wep1Radio->setChecked(true);
751                         break;
752                 case 2:
753                         wep2Radio->setChecked(true);
754                         break;
755                 case 3:
756                         wep3Radio->setChecked(true);
757                         break;
758                 }
759         }
760
761         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d id_str", network_id);
762         reply_len = sizeof(reply) - 1;
763         if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
764             reply_len >= 2 && reply[0] == '"') {
765                 reply[reply_len] = '\0';
766                 pos = strchr(reply + 1, '"');
767                 if (pos)
768                         *pos = '\0';
769                 idstrEdit->setText(reply + 1);
770         }
771
772         snprintf(cmd, sizeof(cmd), "GET_NETWORK %d priority", network_id);
773         reply_len = sizeof(reply) - 1;
774         if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
775         {
776                 reply[reply_len] = '\0';
777                 prioritySpinBox->setValue(atoi(reply));
778         }
779
780         authSelect->setCurrentIndex(auth);
781         authChanged(auth);
782         encrSelect->setCurrentIndex(encr);
783         wepEnabled(auth == AUTH_NONE_WEP || auth == AUTH_NONE_WEP_SHARED);
784
785         removeButton->setEnabled(true);
786         addButton->setText("Save");
787 }
788
789
790 void NetworkConfig::removeNetwork()
791 {
792         char reply[10], cmd[256];
793         size_t reply_len;
794
795         if (QMessageBox::information(this, "wpa_gui",
796                                      "This will permanently remove the "
797                                      "network\n"
798                                      "from the configuration. Do you really "
799                                      "want\n"
800                                      "to remove this network?", "Yes", "No")
801             != 0)
802                 return;
803
804         snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
805         reply_len = sizeof(reply);
806         wpagui->ctrlRequest(cmd, reply, &reply_len);
807         if (strncmp(reply, "OK", 2) != 0) {
808                 QMessageBox::warning(this, "wpa_gui",
809                                      "Failed to remove network from "
810                                      "wpa_supplicant\n"
811                                      "configuration.");
812         } else {
813                 wpagui->triggerUpdate();
814                 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
815         }
816
817         close();
818 }
819
820
821 void NetworkConfig::newNetwork()
822 {
823         new_network = true;
824         getEapCapa();
825 }
826
827
828 void NetworkConfig::getEapCapa()
829 {
830         char reply[256];
831         size_t reply_len;
832
833         if (wpagui == NULL)
834                 return;
835
836         reply_len = sizeof(reply) - 1;
837         if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
838                 return;
839         reply[reply_len] = '\0';
840
841         QString res(reply);
842         QStringList types = res.split(QChar(' '));
843         eapSelect->insertItems(-1, types);
844 }
845
846
847 void NetworkConfig::useWps()
848 {
849         if (wpagui == NULL)
850                 return;
851         wpagui->setBssFromScan(bssid);
852         wpagui->wpsDialog();
853         close();
854 }