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