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