2 * wpa_gui - NetworkConfig class
3 * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include <QMessageBox>
17 #include "networkconfig.h"
29 #define WPA_GUI_KEY_DATA "[key is configured]"
32 NetworkConfig::NetworkConfig(QWidget *parent, const char *, bool, Qt::WFlags)
37 connect(authSelect, SIGNAL(activated(int)), this,
38 SLOT(authChanged(int)));
39 connect(cancelButton, SIGNAL(clicked()), this, SLOT(close()));
40 connect(addButton, SIGNAL(clicked()), this, SLOT(addNetwork()));
41 connect(encrSelect, SIGNAL(activated(const QString &)), this,
42 SLOT(encrChanged(const QString &)));
43 connect(removeButton, SIGNAL(clicked()), this, SLOT(removeNetwork()));
50 NetworkConfig::~NetworkConfig()
55 void NetworkConfig::languageChange()
61 void NetworkConfig::paramsFromScanResults(QTreeWidgetItem *sel)
65 /* SSID BSSID frequency signal flags */
66 setWindowTitle(sel->text(0));
67 ssidEdit->setText(sel->text(0));
69 QString flags = sel->text(4);
71 if (flags.indexOf("[WPA2-EAP") >= 0)
73 else if (flags.indexOf("[WPA-EAP") >= 0)
75 else if (flags.indexOf("[WPA2-PSK") >= 0)
77 else if (flags.indexOf("[WPA-PSK") >= 0)
82 if (flags.indexOf("-CCMP") >= 0)
84 else if (flags.indexOf("-TKIP") >= 0)
86 else if (flags.indexOf("WEP") >= 0)
91 authSelect->setCurrentIndex(auth);
93 encrSelect->setCurrentIndex(encr);
95 wepEnabled(auth == AUTH_NONE && encr == 1);
101 void NetworkConfig::authChanged(int sel)
103 pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK);
104 bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP ||
105 sel == AUTH_WPA2_EAP;
106 eapSelect->setEnabled(eap);
107 identityEdit->setEnabled(eap);
108 passwordEdit->setEnabled(eap);
109 cacertEdit->setEnabled(eap);
111 while (encrSelect->count())
112 encrSelect->removeItem(0);
114 if (sel == AUTH_NONE || sel == AUTH_IEEE8021X) {
115 encrSelect->addItem("None");
116 encrSelect->addItem("WEP");
117 encrSelect->setCurrentIndex(sel == AUTH_NONE ? 0 : 1);
119 encrSelect->addItem("TKIP");
120 encrSelect->addItem("CCMP");
121 encrSelect->setCurrentIndex((sel == AUTH_WPA2_PSK ||
122 sel == AUTH_WPA2_EAP) ? 1 : 0);
125 wepEnabled(sel == AUTH_IEEE8021X);
129 void NetworkConfig::addNetwork()
131 char reply[10], cmd[256];
134 int psklen = pskEdit->text().length();
135 int auth = authSelect->currentIndex();
137 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) {
138 if (psklen < 8 || psklen > 64) {
139 QMessageBox::warning(this, "WPA Pre-Shared Key Error",
140 "WPA-PSK requires a passphrase "
141 "of 8 to 63 characters\n"
142 "or 64 hex digit PSK");
148 if (idstrEdit->isEnabled() && !idstrEdit->text().isEmpty()) {
149 QRegExp rx("^(\\w|-)+$");
150 if (rx.indexIn(idstrEdit->text()) < 0) {
151 QMessageBox::warning(this, "Network ID Error",
152 "Network ID String contains "
153 "non-word characters.\n"
154 "It must be a simple string, "
155 "without spaces, containing\n"
156 "only characters in this range: "
158 idstrEdit->setFocus();
166 memset(reply, 0, sizeof(reply));
167 reply_len = sizeof(reply) - 1;
170 wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len);
171 if (reply[0] == 'F') {
172 QMessageBox::warning(this, "wpa_gui", "Failed to add "
173 "network to wpa_supplicant\n"
179 id = edit_network_id;
181 setNetworkParam(id, "ssid", ssidEdit->text().toAscii().constData(),
184 const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
190 key_mgmt = "IEEE8021X";
193 key_mgmt = "WPA-PSK";
197 key_mgmt = "WPA-EAP";
201 key_mgmt = "WPA-PSK";
205 key_mgmt = "WPA-EAP";
210 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
211 auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
212 int encr = encrSelect->currentIndex();
220 setNetworkParam(id, "proto", proto, false);
222 setNetworkParam(id, "key_mgmt", key_mgmt, false);
224 setNetworkParam(id, "pairwise", pairwise, false);
225 setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
227 if (pskEdit->isEnabled() &&
228 strcmp(passwordEdit->text().toAscii().constData(),
229 WPA_GUI_KEY_DATA) != 0)
230 setNetworkParam(id, "psk",
231 pskEdit->text().toAscii().constData(),
233 if (eapSelect->isEnabled()) {
235 eapSelect->currentText().toAscii().constData();
236 setNetworkParam(id, "eap", eap, false);
237 if (strcmp(eap, "SIM") == 0 || strcmp(eap, "AKA") == 0)
238 setNetworkParam(id, "pcsc", "", true);
240 if (identityEdit->isEnabled())
241 setNetworkParam(id, "identity",
242 identityEdit->text().toAscii().constData(),
244 if (passwordEdit->isEnabled() &&
245 strcmp(passwordEdit->text().toAscii().constData(),
246 WPA_GUI_KEY_DATA) != 0)
247 setNetworkParam(id, "password",
248 passwordEdit->text().toAscii().constData(),
250 if (cacertEdit->isEnabled())
251 setNetworkParam(id, "ca_cert",
252 cacertEdit->text().toAscii().constData(),
254 writeWepKey(id, wep0Edit, 0);
255 writeWepKey(id, wep1Edit, 1);
256 writeWepKey(id, wep2Edit, 2);
257 writeWepKey(id, wep3Edit, 3);
259 if (wep0Radio->isEnabled() && wep0Radio->isChecked())
260 setNetworkParam(id, "wep_tx_keyidx", "0", false);
261 else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
262 setNetworkParam(id, "wep_tx_keyidx", "1", false);
263 else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
264 setNetworkParam(id, "wep_tx_keyidx", "2", false);
265 else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
266 setNetworkParam(id, "wep_tx_keyidx", "3", false);
268 if (idstrEdit->isEnabled())
269 setNetworkParam(id, "id_str",
270 idstrEdit->text().toAscii().constData(),
273 if (prioritySpinBox->isEnabled()) {
275 prio = prio.setNum(prioritySpinBox->value());
276 setNetworkParam(id, "priority", prio.toAscii().constData(),
280 snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
281 reply_len = sizeof(reply);
282 wpagui->ctrlRequest(cmd, reply, &reply_len);
283 if (strncmp(reply, "OK", 2) != 0) {
284 QMessageBox::warning(this, "wpa_gui", "Failed to enable "
285 "network in wpa_supplicant\n"
287 /* Network was added, so continue anyway */
289 wpagui->triggerUpdate();
290 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
296 void NetworkConfig::setWpaGui(WpaGui *_wpagui)
302 int NetworkConfig::setNetworkParam(int id, const char *field,
303 const char *value, bool quote)
305 char reply[10], cmd[256];
307 snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
308 id, field, quote ? "\"" : "", value, quote ? "\"" : "");
309 reply_len = sizeof(reply);
310 wpagui->ctrlRequest(cmd, reply, &reply_len);
311 return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
315 void NetworkConfig::encrChanged(const QString &sel)
317 wepEnabled(sel.indexOf("WEP") == 0);
321 void NetworkConfig::wepEnabled(bool enabled)
323 wep0Edit->setEnabled(enabled);
324 wep1Edit->setEnabled(enabled);
325 wep2Edit->setEnabled(enabled);
326 wep3Edit->setEnabled(enabled);
327 wep0Radio->setEnabled(enabled);
328 wep1Radio->setEnabled(enabled);
329 wep2Radio->setEnabled(enabled);
330 wep3Radio->setEnabled(enabled);
334 void NetworkConfig::writeWepKey(int network_id, QLineEdit *edit, int id)
338 const char *txt, *pos;
341 if (!edit->isEnabled() || edit->text().isEmpty())
345 * Assume hex key if only hex characters are present and length matches
346 * with 40, 104, or 128-bit key
348 txt = edit->text().toAscii().constData();
349 if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
357 if (!((*pos >= '0' && *pos <= '9') ||
358 (*pos >= 'a' && *pos <= 'f') ||
359 (*pos >= 'A' && *pos <= 'F'))) {
365 if (hex && len != 10 && len != 26 && len != 32)
367 snprintf(buf, sizeof(buf), "wep_key%d", id);
368 setNetworkParam(network_id, buf, txt, !hex);
372 static int key_value_isset(const char *reply, size_t reply_len)
374 return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
378 void NetworkConfig::paramsFromConfig(int network_id)
382 edit_network_id = network_id;
385 char reply[1024], cmd[256], *pos;
388 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
389 reply_len = sizeof(reply) - 1;
390 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
391 reply_len >= 2 && reply[0] == '"') {
392 reply[reply_len] = '\0';
393 pos = strchr(reply + 1, '"');
396 ssidEdit->setText(reply + 1);
399 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
400 reply_len = sizeof(reply) - 1;
402 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
403 reply[reply_len] = '\0';
404 if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
406 else if (strstr(reply, "WPA"))
410 int auth = AUTH_NONE, encr = 0;
411 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
412 reply_len = sizeof(reply) - 1;
413 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
414 reply[reply_len] = '\0';
415 if (strstr(reply, "WPA-EAP"))
416 auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
417 else if (strstr(reply, "WPA-PSK"))
418 auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
419 else if (strstr(reply, "IEEE8021X")) {
420 auth = AUTH_IEEE8021X;
425 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
426 reply_len = sizeof(reply) - 1;
427 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
428 reply[reply_len] = '\0';
429 if (strstr(reply, "CCMP") && auth != AUTH_NONE)
431 else if (strstr(reply, "TKIP"))
433 else if (strstr(reply, "WEP"))
439 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
440 reply_len = sizeof(reply) - 1;
441 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
442 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
443 reply[reply_len] = '\0';
444 pos = strchr(reply + 1, '"');
447 pskEdit->setText(reply + 1);
448 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
449 pskEdit->setText(WPA_GUI_KEY_DATA);
452 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
453 reply_len = sizeof(reply) - 1;
454 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
455 reply_len >= 2 && reply[0] == '"') {
456 reply[reply_len] = '\0';
457 pos = strchr(reply + 1, '"');
460 identityEdit->setText(reply + 1);
463 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
464 reply_len = sizeof(reply) - 1;
465 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
466 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
467 reply[reply_len] = '\0';
468 pos = strchr(reply + 1, '"');
471 passwordEdit->setText(reply + 1);
472 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
473 passwordEdit->setText(WPA_GUI_KEY_DATA);
476 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
477 reply_len = sizeof(reply) - 1;
478 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
479 reply_len >= 2 && reply[0] == '"') {
480 reply[reply_len] = '\0';
481 pos = strchr(reply + 1, '"');
484 cacertEdit->setText(reply + 1);
487 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
488 reply_len = sizeof(reply) - 1;
489 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
491 reply[reply_len] = '\0';
492 for (i = 0; i < eapSelect->count(); i++) {
493 if (eapSelect->itemText(i).compare(reply) == 0) {
494 eapSelect->setCurrentIndex(i);
500 for (i = 0; i < 4; i++) {
517 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d",
519 reply_len = sizeof(reply) - 1;
520 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
521 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
522 reply[reply_len] = '\0';
523 pos = strchr(reply + 1, '"');
526 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
529 wepEdit->setText(reply + 1);
530 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
531 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
533 wepEdit->setText(WPA_GUI_KEY_DATA);
537 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
538 reply_len = sizeof(reply) - 1;
539 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
541 reply[reply_len] = '\0';
542 switch (atoi(reply)) {
544 wep0Radio->setChecked(true);
547 wep1Radio->setChecked(true);
550 wep2Radio->setChecked(true);
553 wep3Radio->setChecked(true);
558 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d id_str", network_id);
559 reply_len = sizeof(reply) - 1;
560 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
561 reply_len >= 2 && reply[0] == '"') {
562 reply[reply_len] = '\0';
563 pos = strchr(reply + 1, '"');
566 idstrEdit->setText(reply + 1);
569 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d priority", network_id);
570 reply_len = sizeof(reply) - 1;
571 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
573 reply[reply_len] = '\0';
574 prioritySpinBox->setValue(atoi(reply));
577 authSelect->setCurrentIndex(auth);
579 encrSelect->setCurrentIndex(encr);
580 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
581 wepEnabled(encr == 1);
583 removeButton->setEnabled(true);
584 addButton->setText("Save");
588 void NetworkConfig::removeNetwork()
590 char reply[10], cmd[256];
593 if (QMessageBox::information(this, "wpa_gui",
594 "This will permanently remove the "
596 "from the configuration. Do you really "
598 "to remove this network?", "Yes", "No")
602 snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
603 reply_len = sizeof(reply);
604 wpagui->ctrlRequest(cmd, reply, &reply_len);
605 if (strncmp(reply, "OK", 2) != 0) {
606 QMessageBox::warning(this, "wpa_gui",
607 "Failed to remove network from "
611 wpagui->triggerUpdate();
612 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
619 void NetworkConfig::newNetwork()
626 void NetworkConfig::getEapCapa()
634 reply_len = sizeof(reply) - 1;
635 if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
637 reply[reply_len] = '\0';
640 QStringList types = res.split(QChar(' '));
641 eapSelect->insertItems(-1, types);