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