1 /****************************************************************************
2 ** ui.h extension file, included from the uic-generated form implementation.
3 **
4 ** If you want to add, delete, or rename functions or slots, use
5 ** Qt Designer to update this file, preserving your code.
6 **
7 ** You should not define a constructor or destructor in this file.
8 ** Instead, write your code in functions called init() and destroy().
9 ** These will automatically be called by the form's constructor and
10 ** destructor.
11 *****************************************************************************/
12
13 #include <stdlib.h>
14
15 enum {
16 AUTH_NONE = 0,
17 AUTH_IEEE8021X = 1,
18 AUTH_WPA_PSK = 2,
19 AUTH_WPA_EAP = 3,
20 AUTH_WPA2_PSK = 4,
21 AUTH_WPA2_EAP = 5
22 };
23
24 #define WPA_GUI_KEY_DATA "[key is configured]"
25
init()26 void NetworkConfig::init()
27 {
28 wpagui = NULL;
29 new_network = false;
30 }
31
paramsFromScanResults(Q3ListViewItem * sel)32 void NetworkConfig::paramsFromScanResults(Q3ListViewItem *sel)
33 {
34 new_network = true;
35
36 /* SSID BSSID frequency signal flags */
37 setCaption(sel->text(0));
38 ssidEdit->setText(sel->text(0));
39
40 QString flags = sel->text(4);
41 int auth, encr = 0;
42 if (flags.find("[WPA2-EAP") >= 0)
43 auth = AUTH_WPA2_EAP;
44 else if (flags.find("[WPA-EAP") >= 0)
45 auth = AUTH_WPA_EAP;
46 else if (flags.find("[WPA2-PSK") >= 0)
47 auth = AUTH_WPA2_PSK;
48 else if (flags.find("[WPA-PSK") >= 0)
49 auth = AUTH_WPA_PSK;
50 else
51 auth = AUTH_NONE;
52
53 if (flags.find("-CCMP") >= 0)
54 encr = 1;
55 else if (flags.find("-TKIP") >= 0)
56 encr = 0;
57 else if (flags.find("WEP") >= 0)
58 encr = 1;
59 else
60 encr = 0;
61
62 authSelect->setCurrentItem(auth);
63 authChanged(auth);
64 encrSelect->setCurrentItem(encr);
65
66 getEapCapa();
67 }
68
69
authChanged(int sel)70 void NetworkConfig::authChanged(int sel)
71 {
72 pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK);
73 bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP ||
74 sel == AUTH_WPA2_EAP;
75 eapSelect->setEnabled(eap);
76 identityEdit->setEnabled(eap);
77 passwordEdit->setEnabled(eap);
78 cacertEdit->setEnabled(eap);
79
80 while (encrSelect->count())
81 encrSelect->removeItem(0);
82
83 if (sel == AUTH_NONE || sel == AUTH_IEEE8021X) {
84 encrSelect->insertItem("None");
85 encrSelect->insertItem("WEP");
86 encrSelect->setCurrentItem(sel == AUTH_NONE ? 0 : 1);
87 } else {
88 encrSelect->insertItem("TKIP");
89 encrSelect->insertItem("CCMP");
90 encrSelect->setCurrentItem((sel == AUTH_WPA2_PSK ||
91 sel == AUTH_WPA2_EAP) ? 1 : 0);
92 }
93
94 wepEnabled(sel == AUTH_IEEE8021X);
95 }
96
97
addNetwork()98 void NetworkConfig::addNetwork()
99 {
100 char reply[10], cmd[256];
101 size_t reply_len;
102 int id;
103 int psklen = pskEdit->text().length();
104 int auth = authSelect->currentItem();
105
106 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) {
107 if (psklen < 8 || psklen > 64) {
108 QMessageBox::warning(this, "wpa_gui", "WPA-PSK requires a passphrase "
109 "of 8 to 63 characters\n"
110 "or 64 hex digit PSK");
111 return;
112 }
113 }
114
115 if (wpagui == NULL)
116 return;
117
118 memset(reply, 0, sizeof(reply));
119 reply_len = sizeof(reply) - 1;
120
121 if (new_network) {
122 wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len);
123 if (reply[0] == 'F') {
124 QMessageBox::warning(this, "wpa_gui", "Failed to add network to wpa_supplicant\n"
125 "configuration.");
126 return;
127 }
128 id = atoi(reply);
129 } else {
130 id = edit_network_id;
131 }
132
133 setNetworkParam(id, "ssid", ssidEdit->text().ascii(), true);
134
135 const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
136 switch (auth) {
137 case AUTH_NONE:
138 key_mgmt = "NONE";
139 break;
140 case AUTH_IEEE8021X:
141 key_mgmt = "IEEE8021X";
142 break;
143 case AUTH_WPA_PSK:
144 key_mgmt = "WPA-PSK";
145 proto = "WPA";
146 break;
147 case AUTH_WPA_EAP:
148 key_mgmt = "WPA-EAP";
149 proto = "WPA";
150 break;
151 case AUTH_WPA2_PSK:
152 key_mgmt = "WPA-PSK";
153 proto = "WPA2";
154 break;
155 case AUTH_WPA2_EAP:
156 key_mgmt = "WPA-EAP";
157 proto = "WPA2";
158 break;
159 }
160
161 if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
162 auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
163 int encr = encrSelect->currentItem();
164 if (encr == 0)
165 pairwise = "TKIP";
166 else
167 pairwise = "CCMP";
168 }
169
170 if (proto)
171 setNetworkParam(id, "proto", proto, false);
172 if (key_mgmt)
173 setNetworkParam(id, "key_mgmt", key_mgmt, false);
174 if (pairwise) {
175 setNetworkParam(id, "pairwise", pairwise, false);
176 setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
177 }
178 if (pskEdit->isEnabled() &&
179 strcmp(passwordEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
180 setNetworkParam(id, "psk", pskEdit->text().ascii(), psklen != 64);
181 if (eapSelect->isEnabled())
182 setNetworkParam(id, "eap", eapSelect->currentText().ascii(), false);
183 if (identityEdit->isEnabled())
184 setNetworkParam(id, "identity", identityEdit->text().ascii(), true);
185 if (passwordEdit->isEnabled() &&
186 strcmp(passwordEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
187 setNetworkParam(id, "password", passwordEdit->text().ascii(), true);
188 if (cacertEdit->isEnabled())
189 setNetworkParam(id, "ca_cert", cacertEdit->text().ascii(), true);
190 writeWepKey(id, wep0Edit, 0);
191 writeWepKey(id, wep1Edit, 1);
192 writeWepKey(id, wep2Edit, 2);
193 writeWepKey(id, wep3Edit, 3);
194
195 if (wep0Radio->isEnabled() && wep0Radio->isChecked())
196 setNetworkParam(id, "wep_tx_keyidx", "0", false);
197 else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
198 setNetworkParam(id, "wep_tx_keyidx", "1", false);
199 else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
200 setNetworkParam(id, "wep_tx_keyidx", "2", false);
201 else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
202 setNetworkParam(id, "wep_tx_keyidx", "3", false);
203
204 snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
205 reply_len = sizeof(reply);
206 wpagui->ctrlRequest(cmd, reply, &reply_len);
207 if (strncmp(reply, "OK", 2) != 0) {
208 QMessageBox::warning(this, "wpa_gui", "Failed to enable network in wpa_supplicant\n"
209 "configuration.");
210 /* Network was added, so continue anyway */
211 }
212 wpagui->triggerUpdate();
213 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
214
215 close();
216 }
217
218
setWpaGui(WpaGui * _wpagui)219 void NetworkConfig::setWpaGui( WpaGui *_wpagui )
220 {
221 wpagui = _wpagui;
222 }
223
224
setNetworkParam(int id,const char * field,const char * value,bool quote)225 int NetworkConfig::setNetworkParam(int id, const char *field, const char *value, bool quote)
226 {
227 char reply[10], cmd[256];
228 size_t reply_len;
229 snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
230 id, field, quote ? "\"" : "", value, quote ? "\"" : "");
231 reply_len = sizeof(reply);
232 wpagui->ctrlRequest(cmd, reply, &reply_len);
233 return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
234 }
235
236
encrChanged(const QString & sel)237 void NetworkConfig::encrChanged( const QString &sel )
238 {
239 wepEnabled(sel.find("WEP") == 0);
240 }
241
242
wepEnabled(bool enabled)243 void NetworkConfig::wepEnabled( bool enabled )
244 {
245 wep0Edit->setEnabled(enabled);
246 wep1Edit->setEnabled(enabled);
247 wep2Edit->setEnabled(enabled);
248 wep3Edit->setEnabled(enabled);
249 wep0Radio->setEnabled(enabled);
250 wep1Radio->setEnabled(enabled);
251 wep2Radio->setEnabled(enabled);
252 wep3Radio->setEnabled(enabled);
253 }
254
255
writeWepKey(int network_id,QLineEdit * edit,int id)256 void NetworkConfig::writeWepKey( int network_id, QLineEdit *edit, int id )
257 {
258 char buf[10];
259 bool hex;
260 const char *txt, *pos;
261 size_t len;
262
263 if (!edit->isEnabled() || edit->text().isEmpty())
264 return;
265
266 /*
267 * Assume hex key if only hex characters are present and length matches
268 * with 40, 104, or 128-bit key
269 */
270 txt = edit->text().ascii();
271 if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
272 return;
273 len = strlen(txt);
274 if (len == 0)
275 return;
276 pos = txt;
277 hex = true;
278 while (*pos) {
279 if (!((*pos >= '0' && *pos <= '9') || (*pos >= 'a' && *pos <= 'f') ||
280 (*pos >= 'A' && *pos <= 'F'))) {
281 hex = false;
282 break;
283 }
284 pos++;
285 }
286 if (hex && len != 10 && len != 26 && len != 32)
287 hex = false;
288 snprintf(buf, sizeof(buf), "wep_key%d", id);
289 setNetworkParam(network_id, buf, txt, !hex);
290 }
291
292
key_value_isset(const char * reply,size_t reply_len)293 static int key_value_isset(const char *reply, size_t reply_len)
294 {
295 return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
296 }
297
298
paramsFromConfig(int network_id)299 void NetworkConfig::paramsFromConfig( int network_id )
300 {
301 int i, res;
302
303 edit_network_id = network_id;
304 getEapCapa();
305
306 char reply[1024], cmd[256], *pos;
307 size_t reply_len;
308
309 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
310 reply_len = sizeof(reply) - 1;
311 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
312 reply[0] == '"') {
313 reply[reply_len] = '\0';
314 pos = strchr(reply + 1, '"');
315 if (pos)
316 *pos = '\0';
317 ssidEdit->setText(reply + 1);
318 }
319
320 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
321 reply_len = sizeof(reply) - 1;
322 int wpa = 0;
323 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
324 reply[reply_len] = '\0';
325 if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
326 wpa = 2;
327 else if (strstr(reply, "WPA"))
328 wpa = 1;
329 }
330
331 int auth = AUTH_NONE, encr = 0;
332 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
333 reply_len = sizeof(reply) - 1;
334 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
335 reply[reply_len] = '\0';
336 if (strstr(reply, "WPA-EAP"))
337 auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
338 else if (strstr(reply, "WPA-PSK"))
339 auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
340 else if (strstr(reply, "IEEE8021X")) {
341 auth = AUTH_IEEE8021X;
342 encr = 1;
343 }
344 }
345
346 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
347 reply_len = sizeof(reply) - 1;
348 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
349 reply[reply_len] = '\0';
350 if (strstr(reply, "CCMP"))
351 encr = 1;
352 else if (strstr(reply, "TKIP"))
353 encr = 0;
354 else if (strstr(reply, "WEP"))
355 encr = 1;
356 else
357 encr = 0;
358 }
359
360 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
361 reply_len = sizeof(reply) - 1;
362 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
363 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
364 reply[reply_len] = '\0';
365 pos = strchr(reply + 1, '"');
366 if (pos)
367 *pos = '\0';
368 pskEdit->setText(reply + 1);
369 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
370 pskEdit->setText(WPA_GUI_KEY_DATA);
371 }
372
373 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
374 reply_len = sizeof(reply) - 1;
375 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
376 reply[0] == '"') {
377 reply[reply_len] = '\0';
378 pos = strchr(reply + 1, '"');
379 if (pos)
380 *pos = '\0';
381 identityEdit->setText(reply + 1);
382 }
383
384 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
385 reply_len = sizeof(reply) - 1;
386 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
387 if (res >= 0 && reply_len >= 2 &&
388 reply[0] == '"') {
389 reply[reply_len] = '\0';
390 pos = strchr(reply + 1, '"');
391 if (pos)
392 *pos = '\0';
393 passwordEdit->setText(reply + 1);
394 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
395 passwordEdit->setText(WPA_GUI_KEY_DATA);
396 }
397
398 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
399 reply_len = sizeof(reply) - 1;
400 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
401 reply[0] == '"') {
402 reply[reply_len] = '\0';
403 pos = strchr(reply + 1, '"');
404 if (pos)
405 *pos = '\0';
406 cacertEdit->setText(reply + 1);
407 }
408
409 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
410 reply_len = sizeof(reply) - 1;
411 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
412 reply[reply_len] = '\0';
413 for (i = 0; i < eapSelect->count(); i++) {
414 if (eapSelect->text(i).compare(reply) == 0) {
415 eapSelect->setCurrentItem(i);
416 break;
417 }
418 }
419 }
420
421 for (i = 0; i < 4; i++) {
422 QLineEdit *wepEdit;
423 switch (i) {
424 default:
425 case 0:
426 wepEdit = wep0Edit;
427 break;
428 case 1:
429 wepEdit = wep1Edit;
430 break;
431 case 2:
432 wepEdit = wep2Edit;
433 break;
434 case 3:
435 wepEdit = wep3Edit;
436 break;
437 }
438 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d", network_id, i);
439 reply_len = sizeof(reply) - 1;
440 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
441 if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
442 reply[reply_len] = '\0';
443 pos = strchr(reply + 1, '"');
444 if (pos)
445 *pos = '\0';
446 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
447 encr = 1;
448
449 wepEdit->setText(reply + 1);
450 } else if (res >= 0 && key_value_isset(reply, reply_len)) {
451 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
452 encr = 1;
453 wepEdit->setText(WPA_GUI_KEY_DATA);
454 }
455 }
456
457 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
458 reply_len = sizeof(reply) - 1;
459 if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
460 reply[reply_len] = '\0';
461 switch (atoi(reply)) {
462 case 0:
463 wep0Radio->setChecked(true);
464 break;
465 case 1:
466 wep1Radio->setChecked(true);
467 break;
468 case 2:
469 wep2Radio->setChecked(true);
470 break;
471 case 3:
472 wep3Radio->setChecked(true);
473 break;
474 }
475 }
476
477 authSelect->setCurrentItem(auth);
478 authChanged(auth);
479 encrSelect->setCurrentItem(encr);
480 if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
481 wepEnabled(encr == 1);
482
483 removeButton->setEnabled(true);
484 addButton->setText("Save");
485 }
486
487
removeNetwork()488 void NetworkConfig::removeNetwork()
489 {
490 char reply[10], cmd[256];
491 size_t reply_len;
492
493 if (QMessageBox::information(this, "wpa_gui",
494 "This will permanently remove the network\n"
495 "from the configuration. Do you really want\n"
496 "to remove this network?", "Yes", "No") != 0)
497 return;
498
499 snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
500 reply_len = sizeof(reply);
501 wpagui->ctrlRequest(cmd, reply, &reply_len);
502 if (strncmp(reply, "OK", 2) != 0) {
503 QMessageBox::warning(this, "wpa_gui",
504 "Failed to remove network from wpa_supplicant\n"
505 "configuration.");
506 } else {
507 wpagui->triggerUpdate();
508 wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
509 }
510
511 close();
512 }
513
514
newNetwork()515 void NetworkConfig::newNetwork()
516 {
517 new_network = true;
518 getEapCapa();
519 }
520
521
getEapCapa()522 void NetworkConfig::getEapCapa()
523 {
524 char reply[256];
525 size_t reply_len;
526
527 if (wpagui == NULL)
528 return;
529
530 reply_len = sizeof(reply) - 1;
531 if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
532 return;
533 reply[reply_len] = '\0';
534
535 QString res(reply);
536 QStringList types = QStringList::split(QChar(' '), res);
537 eapSelect->insertStringList(types);
538 }
539