Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / wpa / wpa_supplicant / wpa_gui-qt4 / networkconfig.cpp
blobe4f10969b8a1667e0a664bc1d4ed58017ab40d90
1 /*
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
10 * license.
12 * See README and COPYING for more details.
15 #include <QMessageBox>
17 #include "networkconfig.h"
18 #include "wpagui.h"
20 enum {
21 AUTH_NONE = 0,
22 AUTH_IEEE8021X = 1,
23 AUTH_WPA_PSK = 2,
24 AUTH_WPA_EAP = 3,
25 AUTH_WPA2_PSK = 4,
26 AUTH_WPA2_EAP = 5
29 #define WPA_GUI_KEY_DATA "[key is configured]"
32 NetworkConfig::NetworkConfig(QWidget *parent, const char *, bool, Qt::WFlags)
33 : QDialog(parent)
35 setupUi(this);
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()));
45 wpagui = NULL;
46 new_network = false;
50 NetworkConfig::~NetworkConfig()
55 void NetworkConfig::languageChange()
57 retranslateUi(this);
61 void NetworkConfig::paramsFromScanResults(QTreeWidgetItem *sel)
63 new_network = true;
65 /* SSID BSSID frequency signal flags */
66 setWindowTitle(sel->text(0));
67 ssidEdit->setText(sel->text(0));
69 QString flags = sel->text(4);
70 int auth, encr = 0;
71 if (flags.indexOf("[WPA2-EAP") >= 0)
72 auth = AUTH_WPA2_EAP;
73 else if (flags.indexOf("[WPA-EAP") >= 0)
74 auth = AUTH_WPA_EAP;
75 else if (flags.indexOf("[WPA2-PSK") >= 0)
76 auth = AUTH_WPA2_PSK;
77 else if (flags.indexOf("[WPA-PSK") >= 0)
78 auth = AUTH_WPA_PSK;
79 else
80 auth = AUTH_NONE;
82 if (flags.indexOf("-CCMP") >= 0)
83 encr = 1;
84 else if (flags.indexOf("-TKIP") >= 0)
85 encr = 0;
86 else if (flags.indexOf("WEP") >= 0)
87 encr = 1;
88 else
89 encr = 0;
91 authSelect->setCurrentIndex(auth);
92 authChanged(auth);
93 encrSelect->setCurrentIndex(encr);
95 wepEnabled(auth == AUTH_NONE && encr == 1);
97 getEapCapa();
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);
118 } else {
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];
132 size_t reply_len;
133 int id;
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");
143 pskEdit->setFocus();
144 return;
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: "
157 "[A-Za-z0-9_-]\n");
158 idstrEdit->setFocus();
159 return;
163 if (wpagui == NULL)
164 return;
166 memset(reply, 0, sizeof(reply));
167 reply_len = sizeof(reply) - 1;
169 if (new_network) {
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"
174 "configuration.");
175 return;
177 id = atoi(reply);
178 } else
179 id = edit_network_id;
181 setNetworkParam(id, "ssid", ssidEdit->text().toAscii().constData(),
182 true);
184 const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
185 switch (auth) {
186 case AUTH_NONE:
187 key_mgmt = "NONE";
188 break;
189 case AUTH_IEEE8021X:
190 key_mgmt = "IEEE8021X";
191 break;
192 case AUTH_WPA_PSK:
193 key_mgmt = "WPA-PSK";
194 proto = "WPA";
195 break;
196 case AUTH_WPA_EAP:
197 key_mgmt = "WPA-EAP";
198 proto = "WPA";
199 break;
200 case AUTH_WPA2_PSK:
201 key_mgmt = "WPA-PSK";
202 proto = "WPA2";
203 break;
204 case AUTH_WPA2_EAP:
205 key_mgmt = "WPA-EAP";
206 proto = "WPA2";
207 break;
210 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
211 auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
212 int encr = encrSelect->currentIndex();
213 if (encr == 0)
214 pairwise = "TKIP";
215 else
216 pairwise = "CCMP";
219 if (proto)
220 setNetworkParam(id, "proto", proto, false);
221 if (key_mgmt)
222 setNetworkParam(id, "key_mgmt", key_mgmt, false);
223 if (pairwise) {
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(),
232 psklen != 64);
233 if (eapSelect->isEnabled())
234 setNetworkParam(id, "eap",
235 eapSelect->currentText().toAscii().constData(),
236 false);
237 if (identityEdit->isEnabled())
238 setNetworkParam(id, "identity",
239 identityEdit->text().toAscii().constData(),
240 true);
241 if (passwordEdit->isEnabled() &&
242 strcmp(passwordEdit->text().toAscii().constData(),
243 WPA_GUI_KEY_DATA) != 0)
244 setNetworkParam(id, "password",
245 passwordEdit->text().toAscii().constData(),
246 true);
247 if (cacertEdit->isEnabled())
248 setNetworkParam(id, "ca_cert",
249 cacertEdit->text().toAscii().constData(),
250 true);
251 writeWepKey(id, wep0Edit, 0);
252 writeWepKey(id, wep1Edit, 1);
253 writeWepKey(id, wep2Edit, 2);
254 writeWepKey(id, wep3Edit, 3);
256 if (wep0Radio->isEnabled() && wep0Radio->isChecked())
257 setNetworkParam(id, "wep_tx_keyidx", "0", false);
258 else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
259 setNetworkParam(id, "wep_tx_keyidx", "1", false);
260 else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
261 setNetworkParam(id, "wep_tx_keyidx", "2", false);
262 else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
263 setNetworkParam(id, "wep_tx_keyidx", "3", false);
265 if (idstrEdit->isEnabled())
266 setNetworkParam(id, "id_str",
267 idstrEdit->text().toAscii().constData(),
268 true);
270 if (prioritySpinBox->isEnabled()) {
271 QString prio;
272 prio = prio.setNum(prioritySpinBox->value());
273 setNetworkParam(id, "priority", prio.toAscii().constData(),
274 false);
277 snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
278 reply_len = sizeof(reply);
279 wpagui->ctrlRequest(cmd, reply, &reply_len);
280 if (strncmp(reply, "OK", 2) != 0) {
281 QMessageBox::warning(this, "wpa_gui", "Failed to enable "
282 "network in wpa_supplicant\n"
283 "configuration.");
284 /* Network was added, so continue anyway */
286 wpagui->triggerUpdate();
287 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
289 close();
293 void NetworkConfig::setWpaGui(WpaGui *_wpagui)
295 wpagui = _wpagui;
299 int NetworkConfig::setNetworkParam(int id, const char *field,
300 const char *value, bool quote)
302 char reply[10], cmd[256];
303 size_t reply_len;
304 snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
305 id, field, quote ? "\"" : "", value, quote ? "\"" : "");
306 reply_len = sizeof(reply);
307 wpagui->ctrlRequest(cmd, reply, &reply_len);
308 return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
312 void NetworkConfig::encrChanged(const QString &sel)
314 wepEnabled(sel.indexOf("WEP") == 0);
318 void NetworkConfig::wepEnabled(bool enabled)
320 wep0Edit->setEnabled(enabled);
321 wep1Edit->setEnabled(enabled);
322 wep2Edit->setEnabled(enabled);
323 wep3Edit->setEnabled(enabled);
324 wep0Radio->setEnabled(enabled);
325 wep1Radio->setEnabled(enabled);
326 wep2Radio->setEnabled(enabled);
327 wep3Radio->setEnabled(enabled);
331 void NetworkConfig::writeWepKey(int network_id, QLineEdit *edit, int id)
333 char buf[10];
334 bool hex;
335 const char *txt, *pos;
336 size_t len;
338 if (!edit->isEnabled() || edit->text().isEmpty())
339 return;
342 * Assume hex key if only hex characters are present and length matches
343 * with 40, 104, or 128-bit key
345 txt = edit->text().toAscii().constData();
346 if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
347 return;
348 len = strlen(txt);
349 if (len == 0)
350 return;
351 pos = txt;
352 hex = true;
353 while (*pos) {
354 if (!((*pos >= '0' && *pos <= '9') ||
355 (*pos >= 'a' && *pos <= 'f') ||
356 (*pos >= 'A' && *pos <= 'F'))) {
357 hex = false;
358 break;
360 pos++;
362 if (hex && len != 10 && len != 26 && len != 32)
363 hex = false;
364 snprintf(buf, sizeof(buf), "wep_key%d", id);
365 setNetworkParam(network_id, buf, txt, !hex);
369 static int key_value_isset(const char *reply, size_t reply_len)
371 return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
375 void NetworkConfig::paramsFromConfig(int network_id)
377 int i, res;
379 edit_network_id = network_id;
380 getEapCapa();
382 char reply[1024], cmd[256], *pos;
383 size_t reply_len;
385 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
386 reply_len = sizeof(reply) - 1;
387 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
388 reply_len >= 2 && reply[0] == '"') {
389 reply[reply_len] = '\0';
390 pos = strchr(reply + 1, '"');
391 if (pos)
392 *pos = '\0';
393 ssidEdit->setText(reply + 1);
396 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
397 reply_len = sizeof(reply) - 1;
398 int wpa = 0;
399 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
400 reply[reply_len] = '\0';
401 if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
402 wpa = 2;
403 else if (strstr(reply, "WPA"))
404 wpa = 1;
407 int auth = AUTH_NONE, encr = 0;
408 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
409 reply_len = sizeof(reply) - 1;
410 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
411 reply[reply_len] = '\0';
412 if (strstr(reply, "WPA-EAP"))
413 auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
414 else if (strstr(reply, "WPA-PSK"))
415 auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
416 else if (strstr(reply, "IEEE8021X")) {
417 auth = AUTH_IEEE8021X;
418 encr = 1;
422 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
423 reply_len = sizeof(reply) - 1;
424 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
425 reply[reply_len] = '\0';
426 if (strstr(reply, "CCMP") && auth != AUTH_NONE)
427 encr = 1;
428 else if (strstr(reply, "TKIP"))
429 encr = 0;
430 else if (strstr(reply, "WEP"))
431 encr = 1;
432 else
433 encr = 0;
436 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
437 reply_len = sizeof(reply) - 1;
438 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
439 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
440 reply[reply_len] = '\0';
441 pos = strchr(reply + 1, '"');
442 if (pos)
443 *pos = '\0';
444 pskEdit->setText(reply + 1);
445 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
446 pskEdit->setText(WPA_GUI_KEY_DATA);
449 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
450 reply_len = sizeof(reply) - 1;
451 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
452 reply_len >= 2 && reply[0] == '"') {
453 reply[reply_len] = '\0';
454 pos = strchr(reply + 1, '"');
455 if (pos)
456 *pos = '\0';
457 identityEdit->setText(reply + 1);
460 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
461 reply_len = sizeof(reply) - 1;
462 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
463 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
464 reply[reply_len] = '\0';
465 pos = strchr(reply + 1, '"');
466 if (pos)
467 *pos = '\0';
468 passwordEdit->setText(reply + 1);
469 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
470 passwordEdit->setText(WPA_GUI_KEY_DATA);
473 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
474 reply_len = sizeof(reply) - 1;
475 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
476 reply_len >= 2 && reply[0] == '"') {
477 reply[reply_len] = '\0';
478 pos = strchr(reply + 1, '"');
479 if (pos)
480 *pos = '\0';
481 cacertEdit->setText(reply + 1);
484 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
485 reply_len = sizeof(reply) - 1;
486 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
487 reply_len >= 1) {
488 reply[reply_len] = '\0';
489 for (i = 0; i < eapSelect->count(); i++) {
490 if (eapSelect->itemText(i).compare(reply) == 0) {
491 eapSelect->setCurrentIndex(i);
492 break;
497 for (i = 0; i < 4; i++) {
498 QLineEdit *wepEdit;
499 switch (i) {
500 default:
501 case 0:
502 wepEdit = wep0Edit;
503 break;
504 case 1:
505 wepEdit = wep1Edit;
506 break;
507 case 2:
508 wepEdit = wep2Edit;
509 break;
510 case 3:
511 wepEdit = wep3Edit;
512 break;
514 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d",
515 network_id, i);
516 reply_len = sizeof(reply) - 1;
517 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
518 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
519 reply[reply_len] = '\0';
520 pos = strchr(reply + 1, '"');
521 if (pos)
522 *pos = '\0';
523 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
524 encr = 1;
526 wepEdit->setText(reply + 1);
527 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
528 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
529 encr = 1;
530 wepEdit->setText(WPA_GUI_KEY_DATA);
534 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
535 reply_len = sizeof(reply) - 1;
536 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
538 reply[reply_len] = '\0';
539 switch (atoi(reply)) {
540 case 0:
541 wep0Radio->setChecked(true);
542 break;
543 case 1:
544 wep1Radio->setChecked(true);
545 break;
546 case 2:
547 wep2Radio->setChecked(true);
548 break;
549 case 3:
550 wep3Radio->setChecked(true);
551 break;
555 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d id_str", network_id);
556 reply_len = sizeof(reply) - 1;
557 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
558 reply_len >= 2 && reply[0] == '"') {
559 reply[reply_len] = '\0';
560 pos = strchr(reply + 1, '"');
561 if (pos)
562 *pos = '\0';
563 idstrEdit->setText(reply + 1);
566 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d priority", network_id);
567 reply_len = sizeof(reply) - 1;
568 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
570 reply[reply_len] = '\0';
571 prioritySpinBox->setValue(atoi(reply));
574 authSelect->setCurrentIndex(auth);
575 authChanged(auth);
576 encrSelect->setCurrentIndex(encr);
577 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
578 wepEnabled(encr == 1);
580 removeButton->setEnabled(true);
581 addButton->setText("Save");
585 void NetworkConfig::removeNetwork()
587 char reply[10], cmd[256];
588 size_t reply_len;
590 if (QMessageBox::information(this, "wpa_gui",
591 "This will permanently remove the "
592 "network\n"
593 "from the configuration. Do you really "
594 "want\n"
595 "to remove this network?", "Yes", "No")
596 != 0)
597 return;
599 snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
600 reply_len = sizeof(reply);
601 wpagui->ctrlRequest(cmd, reply, &reply_len);
602 if (strncmp(reply, "OK", 2) != 0) {
603 QMessageBox::warning(this, "wpa_gui",
604 "Failed to remove network from "
605 "wpa_supplicant\n"
606 "configuration.");
607 } else {
608 wpagui->triggerUpdate();
609 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
612 close();
616 void NetworkConfig::newNetwork()
618 new_network = true;
619 getEapCapa();
623 void NetworkConfig::getEapCapa()
625 char reply[256];
626 size_t reply_len;
628 if (wpagui == NULL)
629 return;
631 reply_len = sizeof(reply) - 1;
632 if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
633 return;
634 reply[reply_len] = '\0';
636 QString res(reply);
637 QStringList types = res.split(QChar(' '));
638 eapSelect->insertItems(-1, types);