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);