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(textActivated(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  		QRegularExpression rx("^(\\w|-)+$");
208  		if (!rx.match(idstrEdit->text()).hasMatch()) {
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  		    QMessageBox::Yes, QMessageBox::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