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