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(Q3ListViewItem *sel)
65 /* SSID BSSID frequency signal flags */
66 setCaption(sel->text(0));
67 ssidEdit->setText(sel->text(0));
69 QString flags = sel->text(4);
71 if (flags.find("[WPA2-EAP") >= 0)
73 else if (flags.find("[WPA-EAP") >= 0)
75 else if (flags.find("[WPA2-PSK") >= 0)
77 else if (flags.find("[WPA-PSK") >= 0)
82 if (flags.find("-CCMP") >= 0)
84 else if (flags.find("-TKIP") >= 0)
86 else if (flags.find("WEP") >= 0)
91 authSelect->setCurrentItem(auth);
93 encrSelect->setCurrentItem(encr);
99 void NetworkConfig::authChanged(int sel)
101 pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK);
102 bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP ||
103 sel == AUTH_WPA2_EAP;
104 eapSelect->setEnabled(eap);
105 identityEdit->setEnabled(eap);
106 passwordEdit->setEnabled(eap);
107 cacertEdit->setEnabled(eap);
109 while (encrSelect->count())
110 encrSelect->removeItem(0);
112 if (sel == AUTH_NONE || sel == AUTH_IEEE8021X) {
113 encrSelect->insertItem("None");
114 encrSelect->insertItem("WEP");
115 encrSelect->setCurrentItem(sel == AUTH_NONE ? 0 : 1);
117 encrSelect->insertItem("TKIP");
118 encrSelect->insertItem("CCMP");
119 encrSelect->setCurrentItem((sel == AUTH_WPA2_PSK ||
120 sel == AUTH_WPA2_EAP) ? 1 : 0);
123 wepEnabled(sel == AUTH_IEEE8021X);
127 void NetworkConfig::addNetwork()
129 char reply[10], cmd[256];
132 int psklen = pskEdit->text().length();
133 int auth = authSelect->currentItem();
135 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) {
136 if (psklen < 8 || psklen > 64) {
137 QMessageBox::warning(this, "wpa_gui",
138 "WPA-PSK requires a passphrase "
139 "of 8 to 63 characters\n"
140 "or 64 hex digit PSK");
148 memset(reply, 0, sizeof(reply));
149 reply_len = sizeof(reply) - 1;
152 wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len);
153 if (reply[0] == 'F') {
154 QMessageBox::warning(this, "wpa_gui", "Failed to add "
155 "network to wpa_supplicant\n"
161 id = edit_network_id;
163 setNetworkParam(id, "ssid", ssidEdit->text().ascii(), true);
165 char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
171 key_mgmt = "IEEE8021X";
174 key_mgmt = "WPA-PSK";
178 key_mgmt = "WPA-EAP";
182 key_mgmt = "WPA-PSK";
186 key_mgmt = "WPA-EAP";
191 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
192 auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
193 int encr = encrSelect->currentItem();
201 setNetworkParam(id, "proto", proto, false);
203 setNetworkParam(id, "key_mgmt", key_mgmt, false);
205 setNetworkParam(id, "pairwise", pairwise, false);
206 setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
208 if (pskEdit->isEnabled() &&
209 strcmp(passwordEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
210 setNetworkParam(id, "psk", pskEdit->text().ascii(),
212 if (eapSelect->isEnabled())
213 setNetworkParam(id, "eap", eapSelect->currentText().ascii(),
215 if (identityEdit->isEnabled())
216 setNetworkParam(id, "identity", identityEdit->text().ascii(),
218 if (passwordEdit->isEnabled() &&
219 strcmp(passwordEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
220 setNetworkParam(id, "password", passwordEdit->text().ascii(),
222 if (cacertEdit->isEnabled())
223 setNetworkParam(id, "ca_cert", cacertEdit->text().ascii(),
225 writeWepKey(id, wep0Edit, 0);
226 writeWepKey(id, wep1Edit, 1);
227 writeWepKey(id, wep2Edit, 2);
228 writeWepKey(id, wep3Edit, 3);
230 if (wep0Radio->isEnabled() && wep0Radio->isChecked())
231 setNetworkParam(id, "wep_tx_keyidx", "0", false);
232 else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
233 setNetworkParam(id, "wep_tx_keyidx", "1", false);
234 else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
235 setNetworkParam(id, "wep_tx_keyidx", "2", false);
236 else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
237 setNetworkParam(id, "wep_tx_keyidx", "3", false);
239 snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
240 reply_len = sizeof(reply);
241 wpagui->ctrlRequest(cmd, reply, &reply_len);
242 if (strncmp(reply, "OK", 2) != 0) {
243 QMessageBox::warning(this, "wpa_gui", "Failed to enable "
244 "network in wpa_supplicant\n"
246 /* Network was added, so continue anyway */
248 wpagui->triggerUpdate();
249 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
255 void NetworkConfig::setWpaGui(WpaGui *_wpagui)
261 int NetworkConfig::setNetworkParam(int id, const char *field,
262 const char *value, bool quote)
264 char reply[10], cmd[256];
266 snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
267 id, field, quote ? "\"" : "", value, quote ? "\"" : "");
268 reply_len = sizeof(reply);
269 wpagui->ctrlRequest(cmd, reply, &reply_len);
270 return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
274 void NetworkConfig::encrChanged(const QString &sel)
276 wepEnabled(sel.find("WEP") == 0);
280 void NetworkConfig::wepEnabled(bool enabled)
282 wep0Edit->setEnabled(enabled);
283 wep1Edit->setEnabled(enabled);
284 wep2Edit->setEnabled(enabled);
285 wep3Edit->setEnabled(enabled);
286 wep0Radio->setEnabled(enabled);
287 wep1Radio->setEnabled(enabled);
288 wep2Radio->setEnabled(enabled);
289 wep3Radio->setEnabled(enabled);
293 void NetworkConfig::writeWepKey(int network_id, QLineEdit *edit, int id)
297 const char *txt, *pos;
300 if (!edit->isEnabled() || edit->text().isEmpty())
304 * Assume hex key if only hex characters are present and length matches
305 * with 40, 104, or 128-bit key
307 txt = edit->text().ascii();
308 if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
316 if (!((*pos >= '0' && *pos <= '9') ||
317 (*pos >= 'a' && *pos <= 'f') ||
318 (*pos >= 'A' && *pos <= 'F'))) {
324 if (hex && len != 10 && len != 26 && len != 32)
326 snprintf(buf, sizeof(buf), "wep_key%d", id);
327 setNetworkParam(network_id, buf, txt, !hex);
331 static int key_value_isset(const char *reply, size_t reply_len)
333 return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
337 void NetworkConfig::paramsFromConfig(int network_id)
341 edit_network_id = network_id;
344 char reply[1024], cmd[256], *pos;
347 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
348 reply_len = sizeof(reply) - 1;
349 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
350 reply_len >= 2 && reply[0] == '"') {
351 reply[reply_len] = '\0';
352 pos = strchr(reply + 1, '"');
355 ssidEdit->setText(reply + 1);
358 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
359 reply_len = sizeof(reply) - 1;
361 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
362 reply[reply_len] = '\0';
363 if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
365 else if (strstr(reply, "WPA"))
369 int auth = AUTH_NONE, encr = 0;
370 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
371 reply_len = sizeof(reply) - 1;
372 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
373 reply[reply_len] = '\0';
374 if (strstr(reply, "WPA-EAP"))
375 auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
376 else if (strstr(reply, "WPA-PSK"))
377 auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
378 else if (strstr(reply, "IEEE8021X")) {
379 auth = AUTH_IEEE8021X;
384 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
385 reply_len = sizeof(reply) - 1;
386 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
387 reply[reply_len] = '\0';
388 if (strstr(reply, "CCMP"))
390 else if (strstr(reply, "TKIP"))
392 else if (strstr(reply, "WEP"))
398 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
399 reply_len = sizeof(reply) - 1;
400 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
401 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
402 reply[reply_len] = '\0';
403 pos = strchr(reply + 1, '"');
406 pskEdit->setText(reply + 1);
407 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
408 pskEdit->setText(WPA_GUI_KEY_DATA);
411 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
412 reply_len = sizeof(reply) - 1;
413 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
414 reply_len >= 2 && reply[0] == '"') {
415 reply[reply_len] = '\0';
416 pos = strchr(reply + 1, '"');
419 identityEdit->setText(reply + 1);
422 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
423 reply_len = sizeof(reply) - 1;
424 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
425 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
426 reply[reply_len] = '\0';
427 pos = strchr(reply + 1, '"');
430 passwordEdit->setText(reply + 1);
431 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
432 passwordEdit->setText(WPA_GUI_KEY_DATA);
435 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
436 reply_len = sizeof(reply) - 1;
437 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
438 reply_len >= 2 && reply[0] == '"') {
439 reply[reply_len] = '\0';
440 pos = strchr(reply + 1, '"');
443 cacertEdit->setText(reply + 1);
446 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
447 reply_len = sizeof(reply) - 1;
448 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
450 reply[reply_len] = '\0';
451 for (i = 0; i < eapSelect->count(); i++) {
452 if (eapSelect->text(i).compare(reply) == 0) {
453 eapSelect->setCurrentItem(i);
459 for (i = 0; i < 4; i++) {
476 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d",
478 reply_len = sizeof(reply) - 1;
479 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
480 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
481 reply[reply_len] = '\0';
482 pos = strchr(reply + 1, '"');
485 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
488 wepEdit->setText(reply + 1);
489 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
490 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
492 wepEdit->setText(WPA_GUI_KEY_DATA);
496 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
497 reply_len = sizeof(reply) - 1;
498 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
500 reply[reply_len] = '\0';
501 switch (atoi(reply)) {
503 wep0Radio->setChecked(true);
506 wep1Radio->setChecked(true);
509 wep2Radio->setChecked(true);
512 wep3Radio->setChecked(true);
517 authSelect->setCurrentItem(auth);
519 encrSelect->setCurrentItem(encr);
520 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
521 wepEnabled(encr == 1);
523 removeButton->setEnabled(true);
524 addButton->setText("Save");
528 void NetworkConfig::removeNetwork()
530 char reply[10], cmd[256];
533 if (QMessageBox::information(this, "wpa_gui",
534 "This will permanently remove the "
536 "from the configuration. Do you really "
538 "to remove this network?", "Yes", "No")
542 snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
543 reply_len = sizeof(reply);
544 wpagui->ctrlRequest(cmd, reply, &reply_len);
545 if (strncmp(reply, "OK", 2) != 0) {
546 QMessageBox::warning(this, "wpa_gui",
547 "Failed to remove network from "
551 wpagui->triggerUpdate();
552 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
559 void NetworkConfig::newNetwork()
566 void NetworkConfig::getEapCapa()
574 reply_len = sizeof(reply) - 1;
575 if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
577 reply[reply_len] = '\0';
580 QStringList types = QStringList::split(QChar(' '), res);
581 eapSelect->insertStringList(types);