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
15enum {
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
29NetworkConfig::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
51NetworkConfig::~NetworkConfig()
52{
53}
54
55
56void NetworkConfig::languageChange()
57{
58	retranslateUi(this);
59}
60
61
62void 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
108void 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
142void 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
184void 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
420void NetworkConfig::setWpaGui(WpaGui *_wpagui)
421{
422	wpagui = _wpagui;
423}
424
425
426int 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
439void NetworkConfig::encrChanged(const QString &)
440{
441}
442
443
444void 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
457void 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
495static 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
501void 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
789void 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
819void NetworkConfig::newNetwork()
820{
821	new_network = true;
822	getEapCapa();
823}
824
825
826void 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
845void NetworkConfig::useWps()
846{
847	if (wpagui == NULL)
848		return;
849	wpagui->setBssFromScan(bssid);
850	wpagui->wpsDialog();
851	close();
852}
853