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