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