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