• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * wpa_gui - NetworkConfig class
3  * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
4  *
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.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14 
15 #include <cstdio>
16 #include <QMessageBox>
17 
18 #include "networkconfig.h"
19 #include "wpagui.h"
20 
21 enum {
22     AUTH_NONE = 0,
23     AUTH_IEEE8021X = 1,
24     AUTH_WPA_PSK = 2,
25     AUTH_WPA_EAP = 3,
26     AUTH_WPA2_PSK = 4,
27     AUTH_WPA2_EAP = 5
28 };
29 
30 #define WPA_GUI_KEY_DATA "[key is configured]"
31 
32 
NetworkConfig(QWidget * parent,const char *,bool,Qt::WFlags)33 NetworkConfig::NetworkConfig(QWidget *parent, const char *, bool, Qt::WFlags)
34 	: QDialog(parent)
35 {
36 	setupUi(this);
37 
38 	connect(authSelect, SIGNAL(activated(int)), this,
39 		SLOT(authChanged(int)));
40 	connect(cancelButton, SIGNAL(clicked()), this, SLOT(close()));
41 	connect(addButton, SIGNAL(clicked()), this, SLOT(addNetwork()));
42 	connect(encrSelect, SIGNAL(activated(const QString &)), this,
43 		SLOT(encrChanged(const QString &)));
44 	connect(removeButton, SIGNAL(clicked()), this, SLOT(removeNetwork()));
45 	connect(eapSelect, SIGNAL(activated(int)), this,
46 		SLOT(eapChanged(int)));
47 	connect(useWpsButton, SIGNAL(clicked()), this, SLOT(useWps()));
48 
49 	wpagui = NULL;
50 	new_network = false;
51 }
52 
53 
~NetworkConfig()54 NetworkConfig::~NetworkConfig()
55 {
56 }
57 
58 
languageChange()59 void NetworkConfig::languageChange()
60 {
61 	retranslateUi(this);
62 }
63 
64 
paramsFromScanResults(QTreeWidgetItem * sel)65 void NetworkConfig::paramsFromScanResults(QTreeWidgetItem *sel)
66 {
67 	new_network = true;
68 
69 	/* SSID BSSID frequency signal flags */
70 	setWindowTitle(sel->text(0));
71 	ssidEdit->setText(sel->text(0));
72 
73 	QString flags = sel->text(4);
74 	int auth, encr = 0;
75 	if (flags.indexOf("[WPA2-EAP") >= 0)
76 		auth = AUTH_WPA2_EAP;
77 	else if (flags.indexOf("[WPA-EAP") >= 0)
78 		auth = AUTH_WPA_EAP;
79 	else if (flags.indexOf("[WPA2-PSK") >= 0)
80 		auth = AUTH_WPA2_PSK;
81 	else if (flags.indexOf("[WPA-PSK") >= 0)
82 		auth = AUTH_WPA_PSK;
83 	else
84 		auth = AUTH_NONE;
85 
86 	if (flags.indexOf("-CCMP") >= 0)
87 		encr = 1;
88 	else if (flags.indexOf("-TKIP") >= 0)
89 		encr = 0;
90 	else if (flags.indexOf("WEP") >= 0)
91 		encr = 1;
92 	else
93 		encr = 0;
94 
95 	authSelect->setCurrentIndex(auth);
96 	authChanged(auth);
97 	encrSelect->setCurrentIndex(encr);
98 
99 	wepEnabled(auth == AUTH_NONE && encr == 1);
100 
101 	getEapCapa();
102 
103 	if (flags.indexOf("[WPS") >= 0)
104 		useWpsButton->setEnabled(true);
105 	bssid = sel->text(1);
106 }
107 
108 
authChanged(int sel)109 void NetworkConfig::authChanged(int sel)
110 {
111 	pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK);
112 	bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP ||
113 		sel == AUTH_WPA2_EAP;
114 	eapSelect->setEnabled(eap);
115 	identityEdit->setEnabled(eap);
116 	passwordEdit->setEnabled(eap);
117 	cacertEdit->setEnabled(eap);
118 	phase2Select->setEnabled(eap);
119 	if (eap)
120 		eapChanged(eapSelect->currentIndex());
121 
122 	while (encrSelect->count())
123 		encrSelect->removeItem(0);
124 
125 	if (sel == AUTH_NONE || sel == AUTH_IEEE8021X) {
126 		encrSelect->addItem("None");
127 		encrSelect->addItem("WEP");
128 		encrSelect->setCurrentIndex(sel == AUTH_NONE ? 0 : 1);
129 	} else {
130 		encrSelect->addItem("TKIP");
131 		encrSelect->addItem("CCMP");
132 		encrSelect->setCurrentIndex((sel == AUTH_WPA2_PSK ||
133 					     sel == AUTH_WPA2_EAP) ? 1 : 0);
134 	}
135 
136 	wepEnabled(sel == AUTH_IEEE8021X);
137 }
138 
139 
eapChanged(int sel)140 void NetworkConfig::eapChanged(int sel)
141 {
142 	QString prev_val = phase2Select->currentText();
143 	while (phase2Select->count())
144 		phase2Select->removeItem(0);
145 
146 	QStringList inner;
147 	inner << "PEAP" << "TTLS" << "FAST";
148 	if (!inner.contains(eapSelect->itemText(sel)))
149 		return;
150 
151 	phase2Select->addItem("[ any ]");
152 
153 	/* Add special cases based on outer method */
154 	if (eapSelect->currentText().compare("TTLS") == 0) {
155 		phase2Select->addItem("PAP");
156 		phase2Select->addItem("CHAP");
157 		phase2Select->addItem("MSCHAP");
158 		phase2Select->addItem("MSCHAPv2");
159 	} else if (eapSelect->currentText().compare("FAST") == 0)
160 		phase2Select->addItem("GTC(auth) + MSCHAPv2(prov)");
161 
162 	/* Add all enabled EAP methods that can be used in the tunnel */
163 	int i;
164 	QStringList allowed;
165 	allowed << "MSCHAPV2" << "MD5" << "GTC" << "TLS" << "OTP" << "SIM"
166 		<< "AKA";
167 	for (i = 0; i < eapSelect->count(); i++) {
168 		if (allowed.contains(eapSelect->itemText(i))) {
169 			phase2Select->addItem("EAP-" + eapSelect->itemText(i));
170 		}
171 	}
172 
173 	for (i = 0; i < phase2Select->count(); i++) {
174 		if (phase2Select->itemText(i).compare(prev_val) == 0) {
175 			phase2Select->setCurrentIndex(i);
176 			break;
177 		}
178 	}
179 }
180 
181 
addNetwork()182 void NetworkConfig::addNetwork()
183 {
184 	char reply[10], cmd[256];
185 	size_t reply_len;
186 	int id;
187 	int psklen = pskEdit->text().length();
188 	int auth = authSelect->currentIndex();
189 
190 	if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) {
191 		if (psklen < 8 || psklen > 64) {
192 			QMessageBox::warning(this, "WPA Pre-Shared Key Error",
193 					     "WPA-PSK requires a passphrase "
194 					     "of 8 to 63 characters\n"
195 					     "or 64 hex digit PSK");
196 			pskEdit->setFocus();
197 			return;
198 		}
199 	}
200 
201 	if (idstrEdit->isEnabled() && !idstrEdit->text().isEmpty()) {
202 		QRegExp rx("^(\\w|-)+$");
203 		if (rx.indexIn(idstrEdit->text()) < 0) {
204 			QMessageBox::warning(this, "Network ID Error",
205 					     "Network ID String contains "
206 					     "non-word characters.\n"
207 					     "It must be a simple string, "
208 					     "without spaces, containing\n"
209 					     "only characters in this range: "
210 					     "[A-Za-z0-9_-]\n");
211 			idstrEdit->setFocus();
212 			return;
213 		}
214 	}
215 
216 	if (wpagui == NULL)
217 		return;
218 
219 	memset(reply, 0, sizeof(reply));
220 	reply_len = sizeof(reply) - 1;
221 
222 	if (new_network) {
223 		wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len);
224 		if (reply[0] == 'F') {
225 			QMessageBox::warning(this, "wpa_gui", "Failed to add "
226 					     "network to wpa_supplicant\n"
227 					     "configuration.");
228 			return;
229 		}
230 		id = atoi(reply);
231 	} else
232 		id = edit_network_id;
233 
234 	setNetworkParam(id, "ssid", ssidEdit->text().toAscii().constData(),
235 			true);
236 
237 	const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
238 	switch (auth) {
239 	case AUTH_NONE:
240 		key_mgmt = "NONE";
241 		break;
242 	case AUTH_IEEE8021X:
243 		key_mgmt = "IEEE8021X";
244 		break;
245 	case AUTH_WPA_PSK:
246 		key_mgmt = "WPA-PSK";
247 		proto = "WPA";
248 		break;
249 	case AUTH_WPA_EAP:
250 		key_mgmt = "WPA-EAP";
251 		proto = "WPA";
252 		break;
253 	case AUTH_WPA2_PSK:
254 		key_mgmt = "WPA-PSK";
255 		proto = "WPA2";
256 		break;
257 	case AUTH_WPA2_EAP:
258 		key_mgmt = "WPA-EAP";
259 		proto = "WPA2";
260 		break;
261 	}
262 
263 	if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
264 	    auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
265 		int encr = encrSelect->currentIndex();
266 		if (encr == 0)
267 			pairwise = "TKIP";
268 		else
269 			pairwise = "CCMP";
270 	}
271 
272 	if (proto)
273 		setNetworkParam(id, "proto", proto, false);
274 	if (key_mgmt)
275 		setNetworkParam(id, "key_mgmt", key_mgmt, false);
276 	if (pairwise) {
277 		setNetworkParam(id, "pairwise", pairwise, false);
278 		setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
279 	}
280 	if (pskEdit->isEnabled() &&
281 	    strcmp(pskEdit->text().toAscii().constData(),
282 		   WPA_GUI_KEY_DATA) != 0)
283 		setNetworkParam(id, "psk",
284 				pskEdit->text().toAscii().constData(),
285 				psklen != 64);
286 	if (eapSelect->isEnabled()) {
287 		const char *eap =
288 			eapSelect->currentText().toAscii().constData();
289 		setNetworkParam(id, "eap", eap, false);
290 		if (strcmp(eap, "SIM") == 0 || strcmp(eap, "AKA") == 0)
291 			setNetworkParam(id, "pcsc", "", true);
292 		else
293 			setNetworkParam(id, "pcsc", "NULL", false);
294 	}
295 	if (phase2Select->isEnabled()) {
296 		QString eap = eapSelect->currentText();
297 		QString inner = phase2Select->currentText();
298 		char phase2[32];
299 		phase2[0] = '\0';
300 		if (eap.compare("PEAP") == 0) {
301 			if (inner.startsWith("EAP-"))
302 				snprintf(phase2, sizeof(phase2), "auth=%s",
303 					 inner.right(inner.size() - 4).
304 					 toAscii().constData());
305 		} else if (eap.compare("TTLS") == 0) {
306 			if (inner.startsWith("EAP-"))
307 				snprintf(phase2, sizeof(phase2), "autheap=%s",
308 					 inner.right(inner.size() - 4).
309 					 toAscii().constData());
310 			else
311 				snprintf(phase2, sizeof(phase2), "auth=%s",
312 					 inner.toAscii().constData());
313 		} else if (eap.compare("FAST") == 0) {
314 			const char *provisioning = NULL;
315 			if (inner.startsWith("EAP-")) {
316 				snprintf(phase2, sizeof(phase2), "auth=%s",
317 					 inner.right(inner.size() - 4).
318 					 toAscii().constData());
319 				provisioning = "fast_provisioning=2";
320 			} else if (inner.compare("GTC(auth) + MSCHAPv2(prov)")
321 				   == 0) {
322 				snprintf(phase2, sizeof(phase2),
323 					 "auth=GTC auth=MSCHAPV2");
324 				provisioning = "fast_provisioning=1";
325 			} else
326 				provisioning = "fast_provisioning=3";
327 			if (provisioning) {
328 				char blob[32];
329 				setNetworkParam(id, "phase1", provisioning,
330 						true);
331 				snprintf(blob, sizeof(blob),
332 					 "blob://fast-pac-%d", id);
333 				setNetworkParam(id, "pac_file", blob, true);
334 			}
335 		}
336 		if (phase2[0])
337 			setNetworkParam(id, "phase2", phase2, true);
338 		else
339 			setNetworkParam(id, "phase2", "NULL", false);
340 	} else
341 		setNetworkParam(id, "phase2", "NULL", false);
342 	if (identityEdit->isEnabled() && identityEdit->text().length() > 0)
343 		setNetworkParam(id, "identity",
344 				identityEdit->text().toAscii().constData(),
345 				true);
346 	else
347 		setNetworkParam(id, "identity", "NULL", false);
348 	if (passwordEdit->isEnabled() && passwordEdit->text().length() > 0 &&
349 	    strcmp(passwordEdit->text().toAscii().constData(),
350 		   WPA_GUI_KEY_DATA) != 0)
351 		setNetworkParam(id, "password",
352 				passwordEdit->text().toAscii().constData(),
353 				true);
354 	else if (passwordEdit->text().length() == 0)
355 		setNetworkParam(id, "password", "NULL", false);
356 	if (cacertEdit->isEnabled() && cacertEdit->text().length() > 0)
357 		setNetworkParam(id, "ca_cert",
358 				cacertEdit->text().toAscii().constData(),
359 				true);
360 	else
361 		setNetworkParam(id, "ca_cert", "NULL", false);
362 	writeWepKey(id, wep0Edit, 0);
363 	writeWepKey(id, wep1Edit, 1);
364 	writeWepKey(id, wep2Edit, 2);
365 	writeWepKey(id, wep3Edit, 3);
366 
367 	if (wep0Radio->isEnabled() && wep0Radio->isChecked())
368 		setNetworkParam(id, "wep_tx_keyidx", "0", false);
369 	else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
370 		setNetworkParam(id, "wep_tx_keyidx", "1", false);
371 	else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
372 		setNetworkParam(id, "wep_tx_keyidx", "2", false);
373 	else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
374 		setNetworkParam(id, "wep_tx_keyidx", "3", false);
375 
376 	if (idstrEdit->isEnabled() && idstrEdit->text().length() > 0)
377 		setNetworkParam(id, "id_str",
378 				idstrEdit->text().toAscii().constData(),
379 				true);
380 	else
381 		setNetworkParam(id, "id_str", "NULL", false);
382 
383 	if (prioritySpinBox->isEnabled()) {
384 		QString prio;
385 		prio = prio.setNum(prioritySpinBox->value());
386 		setNetworkParam(id, "priority", prio.toAscii().constData(),
387 				false);
388 	}
389 
390 	snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
391 	reply_len = sizeof(reply);
392 	wpagui->ctrlRequest(cmd, reply, &reply_len);
393 	if (strncmp(reply, "OK", 2) != 0) {
394 		QMessageBox::warning(this, "wpa_gui", "Failed to enable "
395 				     "network in wpa_supplicant\n"
396 				     "configuration.");
397 		/* Network was added, so continue anyway */
398 	}
399 	wpagui->triggerUpdate();
400 	wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
401 
402 	close();
403 }
404 
405 
setWpaGui(WpaGui * _wpagui)406 void NetworkConfig::setWpaGui(WpaGui *_wpagui)
407 {
408 	wpagui = _wpagui;
409 }
410 
411 
setNetworkParam(int id,const char * field,const char * value,bool quote)412 int NetworkConfig::setNetworkParam(int id, const char *field,
413 				   const char *value, bool quote)
414 {
415 	char reply[10], cmd[256];
416 	size_t reply_len;
417 	snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
418 		 id, field, quote ? "\"" : "", value, quote ? "\"" : "");
419 	reply_len = sizeof(reply);
420 	wpagui->ctrlRequest(cmd, reply, &reply_len);
421 	return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
422 }
423 
424 
encrChanged(const QString & sel)425 void NetworkConfig::encrChanged(const QString &sel)
426 {
427 	wepEnabled(sel.indexOf("WEP") == 0);
428 }
429 
430 
wepEnabled(bool enabled)431 void NetworkConfig::wepEnabled(bool enabled)
432 {
433 	wep0Edit->setEnabled(enabled);
434 	wep1Edit->setEnabled(enabled);
435 	wep2Edit->setEnabled(enabled);
436 	wep3Edit->setEnabled(enabled);
437 	wep0Radio->setEnabled(enabled);
438 	wep1Radio->setEnabled(enabled);
439 	wep2Radio->setEnabled(enabled);
440 	wep3Radio->setEnabled(enabled);
441 }
442 
443 
writeWepKey(int network_id,QLineEdit * edit,int id)444 void NetworkConfig::writeWepKey(int network_id, QLineEdit *edit, int id)
445 {
446 	char buf[10];
447 	bool hex;
448 	const char *txt, *pos;
449 	size_t len;
450 
451 	if (!edit->isEnabled() || edit->text().isEmpty())
452 		return;
453 
454 	/*
455 	 * Assume hex key if only hex characters are present and length matches
456 	 * with 40, 104, or 128-bit key
457 	 */
458 	txt = edit->text().toAscii().constData();
459 	if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
460 		return;
461 	len = strlen(txt);
462 	if (len == 0)
463 		return;
464 	pos = txt;
465 	hex = true;
466 	while (*pos) {
467 		if (!((*pos >= '0' && *pos <= '9') ||
468 		      (*pos >= 'a' && *pos <= 'f') ||
469 		      (*pos >= 'A' && *pos <= 'F'))) {
470 			hex = false;
471 			break;
472 		}
473 		pos++;
474 	}
475 	if (hex && len != 10 && len != 26 && len != 32)
476 		hex = false;
477 	snprintf(buf, sizeof(buf), "wep_key%d", id);
478 	setNetworkParam(network_id, buf, txt, !hex);
479 }
480 
481 
key_value_isset(const char * reply,size_t reply_len)482 static int key_value_isset(const char *reply, size_t reply_len)
483 {
484     return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
485 }
486 
487 
paramsFromConfig(int network_id)488 void NetworkConfig::paramsFromConfig(int network_id)
489 {
490 	int i, res;
491 
492 	edit_network_id = network_id;
493 	getEapCapa();
494 
495 	char reply[1024], cmd[256], *pos;
496 	size_t reply_len;
497 
498 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
499 	reply_len = sizeof(reply) - 1;
500 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
501 	    reply_len >= 2 && reply[0] == '"') {
502 		reply[reply_len] = '\0';
503 		pos = strchr(reply + 1, '"');
504 		if (pos)
505 			*pos = '\0';
506 		ssidEdit->setText(reply + 1);
507 	}
508 
509 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
510 	reply_len = sizeof(reply) - 1;
511 	int wpa = 0;
512 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
513 		reply[reply_len] = '\0';
514 		if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
515 			wpa = 2;
516 		else if (strstr(reply, "WPA"))
517 			wpa = 1;
518 	}
519 
520 	int auth = AUTH_NONE, encr = 0;
521 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
522 	reply_len = sizeof(reply) - 1;
523 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
524 		reply[reply_len] = '\0';
525 		if (strstr(reply, "WPA-EAP"))
526 			auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
527 		else if (strstr(reply, "WPA-PSK"))
528 			auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
529 		else if (strstr(reply, "IEEE8021X")) {
530 			auth = AUTH_IEEE8021X;
531 			encr = 1;
532 		}
533 	}
534 
535 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
536 	reply_len = sizeof(reply) - 1;
537 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
538 		reply[reply_len] = '\0';
539 		if (strstr(reply, "CCMP") && auth != AUTH_NONE)
540 			encr = 1;
541 		else if (strstr(reply, "TKIP"))
542 			encr = 0;
543 		else if (strstr(reply, "WEP"))
544 			encr = 1;
545 		else
546 			encr = 0;
547 	}
548 
549 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
550 	reply_len = sizeof(reply) - 1;
551 	res = wpagui->ctrlRequest(cmd, reply, &reply_len);
552 	if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
553 		reply[reply_len] = '\0';
554 		pos = strchr(reply + 1, '"');
555 		if (pos)
556 			*pos = '\0';
557 		pskEdit->setText(reply + 1);
558 	} else if (res >= 0 && key_value_isset(reply, reply_len)) {
559 		pskEdit->setText(WPA_GUI_KEY_DATA);
560 	}
561 
562 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
563 	reply_len = sizeof(reply) - 1;
564 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
565 	    reply_len >= 2 && reply[0] == '"') {
566 		reply[reply_len] = '\0';
567 		pos = strchr(reply + 1, '"');
568 		if (pos)
569 			*pos = '\0';
570 		identityEdit->setText(reply + 1);
571 	}
572 
573 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
574 	reply_len = sizeof(reply) - 1;
575 	res = wpagui->ctrlRequest(cmd, reply, &reply_len);
576 	if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
577 		reply[reply_len] = '\0';
578 		pos = strchr(reply + 1, '"');
579 		if (pos)
580 			*pos = '\0';
581 		passwordEdit->setText(reply + 1);
582 	} else if (res >= 0 && key_value_isset(reply, reply_len)) {
583 		passwordEdit->setText(WPA_GUI_KEY_DATA);
584 	}
585 
586 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
587 	reply_len = sizeof(reply) - 1;
588 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
589 	    reply_len >= 2 && reply[0] == '"') {
590 		reply[reply_len] = '\0';
591 		pos = strchr(reply + 1, '"');
592 		if (pos)
593 			*pos = '\0';
594 		cacertEdit->setText(reply + 1);
595 	}
596 
597 	enum { NO_INNER, PEAP_INNER, TTLS_INNER, FAST_INNER } eap = NO_INNER;
598 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
599 	reply_len = sizeof(reply) - 1;
600 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
601 	    reply_len >= 1) {
602 		reply[reply_len] = '\0';
603 		for (i = 0; i < eapSelect->count(); i++) {
604 			if (eapSelect->itemText(i).compare(reply) == 0) {
605 				eapSelect->setCurrentIndex(i);
606 				if (strcmp(reply, "PEAP") == 0)
607 					eap = PEAP_INNER;
608 				else if (strcmp(reply, "TTLS") == 0)
609 					eap = TTLS_INNER;
610 				else if (strcmp(reply, "FAST") == 0)
611 					eap = FAST_INNER;
612 				break;
613 			}
614 		}
615 	}
616 
617 	if (eap != NO_INNER) {
618 		snprintf(cmd, sizeof(cmd), "GET_NETWORK %d phase2",
619 			 network_id);
620 		reply_len = sizeof(reply) - 1;
621 		if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
622 		    reply_len >= 1) {
623 			reply[reply_len] = '\0';
624 			eapChanged(eapSelect->currentIndex());
625 		} else
626 			eap = NO_INNER;
627 	}
628 
629 	char *val;
630 	val = reply + 1;
631 	while (*(val + 1))
632 		val++;
633 	if (*val == '"')
634 		*val = '\0';
635 
636 	switch (eap) {
637 	case PEAP_INNER:
638 		if (strncmp(reply, "\"auth=", 6))
639 			break;
640 		val = reply + 2;
641 		memcpy(val, "EAP-", 4);
642 		break;
643 	case TTLS_INNER:
644 		if (strncmp(reply, "\"autheap=", 9) == 0) {
645 			val = reply + 5;
646 			memcpy(val, "EAP-", 4);
647 		} else if (strncmp(reply, "\"auth=", 6) == 0)
648 			val = reply + 6;
649 		break;
650 	case FAST_INNER:
651 		if (strncmp(reply, "\"auth=", 6))
652 			break;
653 		if (strcmp(reply + 6, "GTC auth=MSCHAPV2") == 0) {
654 			val = (char *) "GTC(auth) + MSCHAPv2(prov)";
655 			break;
656 		}
657 		val = reply + 2;
658 		memcpy(val, "EAP-", 4);
659 		break;
660 	case NO_INNER:
661 		break;
662 	}
663 
664 	for (i = 0; i < phase2Select->count(); i++) {
665 		if (phase2Select->itemText(i).compare(val) == 0) {
666 			phase2Select->setCurrentIndex(i);
667 			break;
668 		}
669 	}
670 
671 	for (i = 0; i < 4; i++) {
672 		QLineEdit *wepEdit;
673 		switch (i) {
674 		default:
675 		case 0:
676 			wepEdit = wep0Edit;
677 			break;
678 		case 1:
679 			wepEdit = wep1Edit;
680 			break;
681 		case 2:
682 			wepEdit = wep2Edit;
683 			break;
684 		case 3:
685 			wepEdit = wep3Edit;
686 			break;
687 		}
688 		snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d",
689 			 network_id, i);
690 		reply_len = sizeof(reply) - 1;
691 		res = wpagui->ctrlRequest(cmd, reply, &reply_len);
692 		if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
693 			reply[reply_len] = '\0';
694 			pos = strchr(reply + 1, '"');
695 			if (pos)
696 				*pos = '\0';
697 			if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
698 				encr = 1;
699 
700 			wepEdit->setText(reply + 1);
701 		} else if (res >= 0 && key_value_isset(reply, reply_len)) {
702 			if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
703 				encr = 1;
704 			wepEdit->setText(WPA_GUI_KEY_DATA);
705 		}
706 	}
707 
708 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
709 	reply_len = sizeof(reply) - 1;
710 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
711 	{
712 		reply[reply_len] = '\0';
713 		switch (atoi(reply)) {
714 		case 0:
715 			wep0Radio->setChecked(true);
716 			break;
717 		case 1:
718 			wep1Radio->setChecked(true);
719 			break;
720 		case 2:
721 			wep2Radio->setChecked(true);
722 			break;
723 		case 3:
724 			wep3Radio->setChecked(true);
725 			break;
726 		}
727 	}
728 
729 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d id_str", network_id);
730 	reply_len = sizeof(reply) - 1;
731 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
732 	    reply_len >= 2 && reply[0] == '"') {
733 		reply[reply_len] = '\0';
734 		pos = strchr(reply + 1, '"');
735 		if (pos)
736 			*pos = '\0';
737 		idstrEdit->setText(reply + 1);
738 	}
739 
740 	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d priority", network_id);
741 	reply_len = sizeof(reply) - 1;
742 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
743 	{
744 		reply[reply_len] = '\0';
745 		prioritySpinBox->setValue(atoi(reply));
746 	}
747 
748 	authSelect->setCurrentIndex(auth);
749 	authChanged(auth);
750 	encrSelect->setCurrentIndex(encr);
751 	if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
752 		wepEnabled(encr == 1);
753 
754 	removeButton->setEnabled(true);
755 	addButton->setText("Save");
756 }
757 
758 
removeNetwork()759 void NetworkConfig::removeNetwork()
760 {
761 	char reply[10], cmd[256];
762 	size_t reply_len;
763 
764 	if (QMessageBox::information(this, "wpa_gui",
765 				     "This will permanently remove the "
766 				     "network\n"
767 				     "from the configuration. Do you really "
768 				     "want\n"
769 				     "to remove this network?", "Yes", "No")
770 	    != 0)
771 		return;
772 
773 	snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
774 	reply_len = sizeof(reply);
775 	wpagui->ctrlRequest(cmd, reply, &reply_len);
776 	if (strncmp(reply, "OK", 2) != 0) {
777 		QMessageBox::warning(this, "wpa_gui",
778 				     "Failed to remove network from "
779 				     "wpa_supplicant\n"
780 				     "configuration.");
781 	} else {
782 		wpagui->triggerUpdate();
783 		wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
784 	}
785 
786 	close();
787 }
788 
789 
newNetwork()790 void NetworkConfig::newNetwork()
791 {
792 	new_network = true;
793 	getEapCapa();
794 }
795 
796 
getEapCapa()797 void NetworkConfig::getEapCapa()
798 {
799 	char reply[256];
800 	size_t reply_len;
801 
802 	if (wpagui == NULL)
803 		return;
804 
805 	reply_len = sizeof(reply) - 1;
806 	if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
807 		return;
808 	reply[reply_len] = '\0';
809 
810 	QString res(reply);
811 	QStringList types = res.split(QChar(' '));
812 	eapSelect->insertItems(-1, types);
813 }
814 
815 
useWps()816 void NetworkConfig::useWps()
817 {
818 	if (wpagui == NULL)
819 		return;
820 	wpagui->setBssFromScan(bssid);
821 	wpagui->wpsDialog();
822 	close();
823 }
824