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,
     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(activated(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 
     52 NetworkConfig::~NetworkConfig()
     53 {
     54 }
     55 
     56 
     57 void NetworkConfig::languageChange()
     58 {
     59 	retranslateUi(this);
     60 }
     61 
     62 
     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 
    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 
    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 
    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 		QRegExp rx("^(\\w|-)+$");
    208 		if (rx.indexIn(idstrEdit->text()) < 0) {
    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 
    421 void NetworkConfig::setWpaGui(WpaGui *_wpagui)
    422 {
    423 	wpagui = _wpagui;
    424 }
    425 
    426 
    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 
    440 void NetworkConfig::encrChanged(const QString &)
    441 {
    442 }
    443 
    444 
    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 
    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 
    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 
    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 
    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 		    tr("Yes"), tr("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 
    820 void NetworkConfig::newNetwork()
    821 {
    822 	new_network = true;
    823 	getEapCapa();
    824 }
    825 
    826 
    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 
    846 void NetworkConfig::useWps()
    847 {
    848 	if (wpagui == NULL)
    849 		return;
    850 	wpagui->setBssFromScan(bssid);
    851 	wpagui->wpsDialog();
    852 	close();
    853 }
    854