• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     if (idstrEdit->isEnabled())
136 	setNetworkParam(id, "id_str", idstrEdit->text().ascii(), true);
137 
138     const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
139     switch (auth) {
140     case AUTH_NONE:
141 	key_mgmt = "NONE";
142 	break;
143     case AUTH_IEEE8021X:
144 	key_mgmt = "IEEE8021X";
145 	break;
146     case AUTH_WPA_PSK:
147 	key_mgmt = "WPA-PSK";
148 	proto = "WPA";
149 	break;
150     case AUTH_WPA_EAP:
151 	key_mgmt = "WPA-EAP";
152 	proto = "WPA";
153 	break;
154     case AUTH_WPA2_PSK:
155 	key_mgmt = "WPA-PSK";
156 	proto = "WPA2";
157 	break;
158     case AUTH_WPA2_EAP:
159 	key_mgmt = "WPA-EAP";
160 	proto = "WPA2";
161 	break;
162     }
163 
164     if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
165 	auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
166 	int encr = encrSelect->currentItem();
167 	if (encr == 0)
168 	    pairwise = "TKIP";
169 	else
170 	    pairwise = "CCMP";
171     }
172 
173     if (proto)
174 	setNetworkParam(id, "proto", proto, false);
175     if (key_mgmt)
176 	setNetworkParam(id, "key_mgmt", key_mgmt, false);
177     if (pairwise) {
178 	setNetworkParam(id, "pairwise", pairwise, false);
179 	setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
180     }
181     if (pskEdit->isEnabled() &&
182 	strcmp(pskEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
183 	setNetworkParam(id, "psk", pskEdit->text().ascii(), psklen != 64);
184     if (eapSelect->isEnabled())
185 	setNetworkParam(id, "eap", eapSelect->currentText().ascii(), false);
186     if (identityEdit->isEnabled())
187 	setNetworkParam(id, "identity", identityEdit->text().ascii(), true);
188     if (passwordEdit->isEnabled() &&
189 	strcmp(passwordEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
190 	setNetworkParam(id, "password", passwordEdit->text().ascii(), true);
191     if (cacertEdit->isEnabled())
192 	setNetworkParam(id, "ca_cert", cacertEdit->text().ascii(), true);
193     writeWepKey(id, wep0Edit, 0);
194     writeWepKey(id, wep1Edit, 1);
195     writeWepKey(id, wep2Edit, 2);
196     writeWepKey(id, wep3Edit, 3);
197 
198     if (wep0Radio->isEnabled() && wep0Radio->isChecked())
199 	setNetworkParam(id, "wep_tx_keyidx", "0", false);
200     else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
201 	setNetworkParam(id, "wep_tx_keyidx", "1", false);
202     else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
203 	setNetworkParam(id, "wep_tx_keyidx", "2", false);
204     else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
205 	setNetworkParam(id, "wep_tx_keyidx", "3", false);
206 
207     snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
208     reply_len = sizeof(reply);
209     wpagui->ctrlRequest(cmd, reply, &reply_len);
210     if (strncmp(reply, "OK", 2) != 0) {
211 	QMessageBox::warning(this, "wpa_gui", "Failed to enable network in wpa_supplicant\n"
212 			     "configuration.");
213 	/* Network was added, so continue anyway */
214     }
215     wpagui->triggerUpdate();
216     wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
217 
218     close();
219 }
220 
221 
setWpaGui(WpaGui * _wpagui)222 void NetworkConfig::setWpaGui( WpaGui *_wpagui )
223 {
224     wpagui = _wpagui;
225 }
226 
227 
setNetworkParam(int id,const char * field,const char * value,bool quote)228 int NetworkConfig::setNetworkParam(int id, const char *field, const char *value, bool quote)
229 {
230     char reply[10], cmd[256];
231     size_t reply_len;
232     snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
233 	     id, field, quote ? "\"" : "", value, quote ? "\"" : "");
234     reply_len = sizeof(reply);
235     wpagui->ctrlRequest(cmd, reply, &reply_len);
236     return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
237 }
238 
239 
encrChanged(const QString & sel)240 void NetworkConfig::encrChanged( const QString &sel )
241 {
242     wepEnabled(sel.find("WEP") == 0);
243 }
244 
245 
wepEnabled(bool enabled)246 void NetworkConfig::wepEnabled( bool enabled )
247 {
248     wep0Edit->setEnabled(enabled);
249     wep1Edit->setEnabled(enabled);
250     wep2Edit->setEnabled(enabled);
251     wep3Edit->setEnabled(enabled);
252     wep0Radio->setEnabled(enabled);
253     wep1Radio->setEnabled(enabled);
254     wep2Radio->setEnabled(enabled);
255     wep3Radio->setEnabled(enabled);
256 }
257 
258 
writeWepKey(int network_id,QLineEdit * edit,int id)259 void NetworkConfig::writeWepKey( int network_id, QLineEdit *edit, int id )
260 {
261     char buf[10];
262     bool hex;
263     const char *txt, *pos;
264     size_t len;
265 
266     if (!edit->isEnabled() || edit->text().isEmpty())
267 	return;
268 
269     /*
270         * Assume hex key if only hex characters are present and length matches
271        * with 40, 104, or 128-bit key
272        */
273     txt = edit->text().ascii();
274     if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
275 	return;
276     len = strlen(txt);
277     if (len == 0)
278 	return;
279     pos = txt;
280     hex = true;
281     while (*pos) {
282 	if (!((*pos >= '0' && *pos <= '9') || (*pos >= 'a' && *pos <= 'f') ||
283 	      (*pos >= 'A' && *pos <= 'F'))) {
284 	    hex = false;
285 	    break;
286 	}
287 	pos++;
288     }
289     if (hex && len != 10 && len != 26 && len != 32)
290 	hex = false;
291     snprintf(buf, sizeof(buf), "wep_key%d", id);
292     setNetworkParam(network_id, buf, txt, !hex);
293 }
294 
295 
key_value_isset(const char * reply,size_t reply_len)296 static int key_value_isset(const char *reply, size_t reply_len)
297 {
298     return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
299 }
300 
301 
paramsFromConfig(int network_id)302 void NetworkConfig::paramsFromConfig( int network_id )
303 {
304     int i, res;
305 
306     edit_network_id = network_id;
307     getEapCapa();
308 
309     char reply[1024], cmd[256], *pos;
310     size_t reply_len;
311 
312     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
313     reply_len = sizeof(reply) - 1;
314     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
315 	reply[0] == '"') {
316 	reply[reply_len] = '\0';
317 	pos = strchr(reply + 1, '"');
318 	if (pos)
319 	    *pos = '\0';
320 	ssidEdit->setText(reply + 1);
321     }
322 
323     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d id_str", network_id);
324     reply_len = sizeof(reply) - 1;
325     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
326 	reply[0] == '"') {
327 	reply[reply_len] = '\0';
328 	pos = strchr(reply + 1, '"');
329 	if (pos)
330 	    *pos = '\0';
331 	idstrEdit->setText(reply + 1);
332     }
333 
334     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
335     reply_len = sizeof(reply) - 1;
336     int wpa = 0;
337     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
338 	reply[reply_len] = '\0';
339 	if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
340 	    wpa = 2;
341 	else if (strstr(reply, "WPA"))
342 	    wpa = 1;
343     }
344 
345     int auth = AUTH_NONE, encr = 0;
346     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", 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, "WPA-EAP"))
351 	    auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
352 	else if (strstr(reply, "WPA-PSK"))
353 	    auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
354 	else if (strstr(reply, "IEEE8021X")) {
355 	    auth = AUTH_IEEE8021X;
356 	    encr = 1;
357 	}
358     }
359 
360     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
361     reply_len = sizeof(reply) - 1;
362     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
363 	reply[reply_len] = '\0';
364 	if (strstr(reply, "CCMP") && auth != AUTH_NONE)
365 	    encr = 1;
366 	else if (strstr(reply, "TKIP"))
367 	    encr = 0;
368 	else if (strstr(reply, "WEP"))
369 	    encr = 1;
370 	else
371 	    encr = 0;
372     }
373 
374     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
375     reply_len = sizeof(reply) - 1;
376     res = wpagui->ctrlRequest(cmd, reply, &reply_len);
377     if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
378 	reply[reply_len] = '\0';
379 	pos = strchr(reply + 1, '"');
380 	if (pos)
381 	    *pos = '\0';
382 	pskEdit->setText(reply + 1);
383     } else if (res >= 0 && key_value_isset(reply, reply_len)) {
384 	pskEdit->setText(WPA_GUI_KEY_DATA);
385     }
386 
387     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
388     reply_len = sizeof(reply) - 1;
389     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
390 	reply[0] == '"') {
391 	reply[reply_len] = '\0';
392 	pos = strchr(reply + 1, '"');
393 	if (pos)
394 	    *pos = '\0';
395 	identityEdit->setText(reply + 1);
396     }
397 
398     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
399     reply_len = sizeof(reply) - 1;
400     res = wpagui->ctrlRequest(cmd, reply, &reply_len);
401     if (res >= 0 && reply_len >= 2 &&
402 	reply[0] == '"') {
403 	reply[reply_len] = '\0';
404 	pos = strchr(reply + 1, '"');
405 	if (pos)
406 	    *pos = '\0';
407 	passwordEdit->setText(reply + 1);
408     } else if (res >= 0 && key_value_isset(reply, reply_len)) {
409 	passwordEdit->setText(WPA_GUI_KEY_DATA);
410     }
411 
412     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
413     reply_len = sizeof(reply) - 1;
414     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
415 	reply[0] == '"') {
416 	reply[reply_len] = '\0';
417 	pos = strchr(reply + 1, '"');
418 	if (pos)
419 	    *pos = '\0';
420 	cacertEdit->setText(reply + 1);
421     }
422 
423     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
424     reply_len = sizeof(reply) - 1;
425     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
426 	reply[reply_len] = '\0';
427 	for (i = 0; i < eapSelect->count(); i++) {
428 	    if (eapSelect->text(i).compare(reply) == 0) {
429 		eapSelect->setCurrentItem(i);
430 		break;
431 	    }
432 	}
433     }
434 
435     for (i = 0; i < 4; i++) {
436 	QLineEdit *wepEdit;
437 	switch (i) {
438 	default:
439 	case 0:
440 	    wepEdit = wep0Edit;
441 	    break;
442 	case 1:
443 	    wepEdit = wep1Edit;
444 	    break;
445 	case 2:
446 	    wepEdit = wep2Edit;
447 	    break;
448 	case 3:
449 	    wepEdit = wep3Edit;
450 	    break;
451 	}
452 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d", network_id, i);
453 	reply_len = sizeof(reply) - 1;
454 	res = wpagui->ctrlRequest(cmd, reply, &reply_len);
455 	if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
456 	    reply[reply_len] = '\0';
457 	    pos = strchr(reply + 1, '"');
458 	    if (pos)
459 		*pos = '\0';
460 	    if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
461 		encr = 1;
462 
463 	    wepEdit->setText(reply + 1);
464 	} else if (res >= 0 && key_value_isset(reply, reply_len)) {
465 	    if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
466 		encr = 1;
467 	    wepEdit->setText(WPA_GUI_KEY_DATA);
468 	}
469     }
470 
471     snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
472     reply_len = sizeof(reply) - 1;
473     if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
474 	reply[reply_len] = '\0';
475 	switch (atoi(reply)) {
476 	case 0:
477 	    wep0Radio->setChecked(true);
478 	    break;
479 	case 1:
480 	    wep1Radio->setChecked(true);
481 	    break;
482 	case 2:
483 	    wep2Radio->setChecked(true);
484 	    break;
485 	case 3:
486 	    wep3Radio->setChecked(true);
487 	    break;
488 	}
489     }
490 
491     authSelect->setCurrentItem(auth);
492     authChanged(auth);
493     encrSelect->setCurrentItem(encr);
494     if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
495 	wepEnabled(encr == 1);
496 
497     removeButton->setEnabled(true);
498     addButton->setText("Save");
499 }
500 
501 
removeNetwork()502 void NetworkConfig::removeNetwork()
503 {
504     char reply[10], cmd[256];
505     size_t reply_len;
506 
507     if (QMessageBox::information(this, "wpa_gui",
508 				 "This will permanently remove the network\n"
509 				 "from the configuration. Do you really want\n"
510 				 "to remove this network?", "Yes", "No") != 0)
511 	return;
512 
513     snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
514     reply_len = sizeof(reply);
515     wpagui->ctrlRequest(cmd, reply, &reply_len);
516     if (strncmp(reply, "OK", 2) != 0) {
517 	QMessageBox::warning(this, "wpa_gui",
518 			     "Failed to remove network from wpa_supplicant\n"
519 			     "configuration.");
520     } else {
521 	wpagui->triggerUpdate();
522 	wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
523     }
524 
525     close();
526 }
527 
528 
newNetwork()529 void NetworkConfig::newNetwork()
530 {
531     new_network = true;
532     getEapCapa();
533 }
534 
535 
getEapCapa()536 void NetworkConfig::getEapCapa()
537 {
538     char reply[256];
539     size_t reply_len;
540 
541     if (wpagui == NULL)
542 	return;
543 
544     reply_len = sizeof(reply) - 1;
545     if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
546 	return;
547     reply[reply_len] = '\0';
548 
549     QString res(reply);
550     QStringList types = QStringList::split(QChar(' '), res);
551     eapSelect->insertStringList(types);
552 }
553