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