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