/*
 * wpa_gui - NetworkConfig class
 * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include <cstdio>
#include <QMessageBox>

#include "networkconfig.h"
#include "wpagui.h"

enum {
	AUTH_NONE_OPEN,
	AUTH_NONE_WEP,
	AUTH_NONE_WEP_SHARED,
	AUTH_IEEE8021X,
	AUTH_WPA_PSK,
	AUTH_WPA_EAP,
	AUTH_WPA2_PSK,
	AUTH_WPA2_EAP
};

#define WPA_GUI_KEY_DATA "[key is configured]"


NetworkConfig::NetworkConfig(QWidget *parent, const char *, bool, Qt::WFlags)
	: QDialog(parent)
{
	setupUi(this);

	encrSelect->setEnabled(false);
	connect(authSelect, SIGNAL(activated(int)), this,
		SLOT(authChanged(int)));
	connect(cancelButton, SIGNAL(clicked()), this, SLOT(close()));
	connect(addButton, SIGNAL(clicked()), this, SLOT(addNetwork()));
	connect(encrSelect, SIGNAL(activated(const QString &)), this,
		SLOT(encrChanged(const QString &)));
	connect(removeButton, SIGNAL(clicked()), this, SLOT(removeNetwork()));
	connect(eapSelect, SIGNAL(activated(int)), this,
		SLOT(eapChanged(int)));
	connect(useWpsButton, SIGNAL(clicked()), this, SLOT(useWps()));

	wpagui = NULL;
	new_network = false;
}


NetworkConfig::~NetworkConfig()
{
}


void NetworkConfig::languageChange()
{
	retranslateUi(this);
}


void NetworkConfig::paramsFromScanResults(QTreeWidgetItem *sel)
{
	new_network = true;

	/* SSID BSSID frequency signal flags */
	setWindowTitle(sel->text(0));
	ssidEdit->setText(sel->text(0));

	QString flags = sel->text(4);
	int auth, encr = 0;
	if (flags.indexOf("[WPA2-EAP") >= 0)
		auth = AUTH_WPA2_EAP;
	else if (flags.indexOf("[WPA-EAP") >= 0)
		auth = AUTH_WPA_EAP;
	else if (flags.indexOf("[WPA2-PSK") >= 0)
		auth = AUTH_WPA2_PSK;
	else if (flags.indexOf("[WPA-PSK") >= 0)
		auth = AUTH_WPA_PSK;
	else
		auth = AUTH_NONE_OPEN;

	if (flags.indexOf("-CCMP") >= 0)
		encr = 1;
	else if (flags.indexOf("-TKIP") >= 0)
		encr = 0;
	else if (flags.indexOf("WEP") >= 0) {
		encr = 1;
		if (auth == AUTH_NONE_OPEN)
			auth = AUTH_NONE_WEP;
	} else
		encr = 0;

	authSelect->setCurrentIndex(auth);
	authChanged(auth);
	encrSelect->setCurrentIndex(encr);

	wepEnabled(auth == AUTH_NONE_WEP);

	getEapCapa();

	if (flags.indexOf("[WPS") >= 0)
		useWpsButton->setEnabled(true);
	bssid = sel->text(1);
}


void NetworkConfig::authChanged(int sel)
{
	encrSelect->setEnabled(sel != AUTH_NONE_OPEN && sel != AUTH_NONE_WEP &&
			       sel != AUTH_NONE_WEP_SHARED);
	pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK);
	bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP ||
		sel == AUTH_WPA2_EAP;
	eapSelect->setEnabled(eap);
	identityEdit->setEnabled(eap);
	passwordEdit->setEnabled(eap);
	cacertEdit->setEnabled(eap);
	phase2Select->setEnabled(eap);
	if (eap)
		eapChanged(eapSelect->currentIndex());

	while (encrSelect->count())
		encrSelect->removeItem(0);

	if (sel == AUTH_NONE_OPEN || sel == AUTH_NONE_WEP ||
	    sel == AUTH_NONE_WEP_SHARED || sel == AUTH_IEEE8021X) {
		encrSelect->addItem("None");
		encrSelect->addItem("WEP");
		encrSelect->setCurrentIndex(sel == AUTH_NONE_OPEN ? 0 : 1);
	} else {
		encrSelect->addItem("TKIP");
		encrSelect->addItem("CCMP");
		encrSelect->setCurrentIndex((sel == AUTH_WPA2_PSK ||
					     sel == AUTH_WPA2_EAP) ? 1 : 0);
	}

	wepEnabled(sel == AUTH_NONE_WEP || sel == AUTH_NONE_WEP_SHARED);
}


void NetworkConfig::eapChanged(int sel)
{
	QString prev_val = phase2Select->currentText();
	while (phase2Select->count())
		phase2Select->removeItem(0);

	QStringList inner;
	inner << "PEAP" << "TTLS" << "FAST";
	if (!inner.contains(eapSelect->itemText(sel)))
		return;

	phase2Select->addItem("[ any ]");

	/* Add special cases based on outer method */
	if (eapSelect->currentText().compare("TTLS") == 0) {
		phase2Select->addItem("PAP");
		phase2Select->addItem("CHAP");
		phase2Select->addItem("MSCHAP");
		phase2Select->addItem("MSCHAPv2");
	} else if (eapSelect->currentText().compare("FAST") == 0)
		phase2Select->addItem("GTC(auth) + MSCHAPv2(prov)");

	/* Add all enabled EAP methods that can be used in the tunnel */
	int i;
	QStringList allowed;
	allowed << "MSCHAPV2" << "MD5" << "GTC" << "TLS" << "OTP" << "SIM"
		<< "AKA";
	for (i = 0; i < eapSelect->count(); i++) {
		if (allowed.contains(eapSelect->itemText(i))) {
			phase2Select->addItem("EAP-" + eapSelect->itemText(i));
		}
	}

	for (i = 0; i < phase2Select->count(); i++) {
		if (phase2Select->itemText(i).compare(prev_val) == 0) {
			phase2Select->setCurrentIndex(i);
			break;
		}
	}
}


void NetworkConfig::addNetwork()
{
	char reply[10], cmd[256];
	size_t reply_len;
	int id;
	int psklen = pskEdit->text().length();
	int auth = authSelect->currentIndex();

	if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) {
		if (psklen < 8 || psklen > 64) {
			QMessageBox::warning(
				this,
				tr("WPA Pre-Shared Key Error"),
				tr("WPA-PSK requires a passphrase of 8 to 63 "
				   "characters\n"
				   "or 64 hex digit PSK"));
			pskEdit->setFocus();
			return;
		}
	}

	if (idstrEdit->isEnabled() && !idstrEdit->text().isEmpty()) {
		QRegExp rx("^(\\w|-)+$");
		if (rx.indexIn(idstrEdit->text()) < 0) {
			QMessageBox::warning(
				this, tr("Network ID Error"),
				tr("Network ID String contains non-word "
				   "characters.\n"
				   "It must be a simple string, "
				   "without spaces, containing\n"
				   "only characters in this range: "
				   "[A-Za-z0-9_-]\n"));
			idstrEdit->setFocus();
			return;
		}
	}

	if (wpagui == NULL)
		return;

	memset(reply, 0, sizeof(reply));
	reply_len = sizeof(reply) - 1;

	if (new_network) {
		wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len);
		if (reply[0] == 'F') {
			QMessageBox::warning(this, "wpa_gui",
					     tr("Failed to add "
						"network to wpa_supplicant\n"
						"configuration."));
			return;
		}
		id = atoi(reply);
	} else
		id = edit_network_id;

	setNetworkParam(id, "ssid", ssidEdit->text().toAscii().constData(),
			true);

	const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
	switch (auth) {
	case AUTH_NONE_OPEN:
	case AUTH_NONE_WEP:
	case AUTH_NONE_WEP_SHARED:
		key_mgmt = "NONE";
		break;
	case AUTH_IEEE8021X:
		key_mgmt = "IEEE8021X";
		break;
	case AUTH_WPA_PSK:
		key_mgmt = "WPA-PSK";
		proto = "WPA";
		break;
	case AUTH_WPA_EAP:
		key_mgmt = "WPA-EAP";
		proto = "WPA";
		break;
	case AUTH_WPA2_PSK:
		key_mgmt = "WPA-PSK";
		proto = "WPA2";
		break;
	case AUTH_WPA2_EAP:
		key_mgmt = "WPA-EAP";
		proto = "WPA2";
		break;
	}

	if (auth == AUTH_NONE_WEP_SHARED)
		setNetworkParam(id, "auth_alg", "SHARED", false);
	else
		setNetworkParam(id, "auth_alg", "OPEN", false);

	if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
	    auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
		int encr = encrSelect->currentIndex();
		if (encr == 0)
			pairwise = "TKIP";
		else
			pairwise = "CCMP";
	}

	if (proto)
		setNetworkParam(id, "proto", proto, false);
	if (key_mgmt)
		setNetworkParam(id, "key_mgmt", key_mgmt, false);
	if (pairwise) {
		setNetworkParam(id, "pairwise", pairwise, false);
		setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
	}
	if (pskEdit->isEnabled() &&
	    strcmp(pskEdit->text().toAscii().constData(),
		   WPA_GUI_KEY_DATA) != 0)
		setNetworkParam(id, "psk",
				pskEdit->text().toAscii().constData(),
				psklen != 64);
	if (eapSelect->isEnabled()) {
		const char *eap =
			eapSelect->currentText().toAscii().constData();
		setNetworkParam(id, "eap", eap, false);
		if (strcmp(eap, "SIM") == 0 || strcmp(eap, "AKA") == 0)
			setNetworkParam(id, "pcsc", "", true);
		else
			setNetworkParam(id, "pcsc", "NULL", false);
	}
	if (phase2Select->isEnabled()) {
		QString eap = eapSelect->currentText();
		QString inner = phase2Select->currentText();
		char phase2[32];
		phase2[0] = '\0';
		if (eap.compare("PEAP") == 0) {
			if (inner.startsWith("EAP-"))
				snprintf(phase2, sizeof(phase2), "auth=%s",
					 inner.right(inner.size() - 4).
					 toAscii().constData());
		} else if (eap.compare("TTLS") == 0) {
			if (inner.startsWith("EAP-"))
				snprintf(phase2, sizeof(phase2), "autheap=%s",
					 inner.right(inner.size() - 4).
					 toAscii().constData());
			else
				snprintf(phase2, sizeof(phase2), "auth=%s",
					 inner.toAscii().constData());
		} else if (eap.compare("FAST") == 0) {
			const char *provisioning = NULL;
			if (inner.startsWith("EAP-")) {
				snprintf(phase2, sizeof(phase2), "auth=%s",
					 inner.right(inner.size() - 4).
					 toAscii().constData());
				provisioning = "fast_provisioning=2";
			} else if (inner.compare("GTC(auth) + MSCHAPv2(prov)")
				   == 0) {
				snprintf(phase2, sizeof(phase2),
					 "auth=GTC auth=MSCHAPV2");
				provisioning = "fast_provisioning=1";
			} else
				provisioning = "fast_provisioning=3";
			if (provisioning) {
				char blob[32];
				setNetworkParam(id, "phase1", provisioning,
						true);
				snprintf(blob, sizeof(blob),
					 "blob://fast-pac-%d", id);
				setNetworkParam(id, "pac_file", blob, true);
			}
		}
		if (phase2[0])
			setNetworkParam(id, "phase2", phase2, true);
		else
			setNetworkParam(id, "phase2", "NULL", false);
	} else
		setNetworkParam(id, "phase2", "NULL", false);
	if (identityEdit->isEnabled() && identityEdit->text().length() > 0)
		setNetworkParam(id, "identity",
				identityEdit->text().toAscii().constData(),
				true);
	else
		setNetworkParam(id, "identity", "NULL", false);
	if (passwordEdit->isEnabled() && passwordEdit->text().length() > 0 &&
	    strcmp(passwordEdit->text().toAscii().constData(),
		   WPA_GUI_KEY_DATA) != 0)
		setNetworkParam(id, "password",
				passwordEdit->text().toAscii().constData(),
				true);
	else if (passwordEdit->text().length() == 0)
		setNetworkParam(id, "password", "NULL", false);
	if (cacertEdit->isEnabled() && cacertEdit->text().length() > 0)
		setNetworkParam(id, "ca_cert",
				cacertEdit->text().toAscii().constData(),
				true);
	else
		setNetworkParam(id, "ca_cert", "NULL", false);
	writeWepKey(id, wep0Edit, 0);
	writeWepKey(id, wep1Edit, 1);
	writeWepKey(id, wep2Edit, 2);
	writeWepKey(id, wep3Edit, 3);

	if (wep0Radio->isEnabled() && wep0Radio->isChecked())
		setNetworkParam(id, "wep_tx_keyidx", "0", false);
	else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
		setNetworkParam(id, "wep_tx_keyidx", "1", false);
	else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
		setNetworkParam(id, "wep_tx_keyidx", "2", false);
	else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
		setNetworkParam(id, "wep_tx_keyidx", "3", false);

	if (idstrEdit->isEnabled() && idstrEdit->text().length() > 0)
		setNetworkParam(id, "id_str",
				idstrEdit->text().toAscii().constData(),
				true);
	else
		setNetworkParam(id, "id_str", "NULL", false);

	if (prioritySpinBox->isEnabled()) {
		QString prio;
		prio = prio.setNum(prioritySpinBox->value());
		setNetworkParam(id, "priority", prio.toAscii().constData(),
				false);
	}

	snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
	reply_len = sizeof(reply);
	wpagui->ctrlRequest(cmd, reply, &reply_len);
	if (strncmp(reply, "OK", 2) != 0) {
		QMessageBox::warning(this, "wpa_gui",
				     tr("Failed to enable "
					"network in wpa_supplicant\n"
					"configuration."));
		/* Network was added, so continue anyway */
	}
	wpagui->triggerUpdate();
	wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);

	close();
}


void NetworkConfig::setWpaGui(WpaGui *_wpagui)
{
	wpagui = _wpagui;
}


int NetworkConfig::setNetworkParam(int id, const char *field,
				   const char *value, bool quote)
{
	char reply[10], cmd[256];
	size_t reply_len;
	snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
		 id, field, quote ? "\"" : "", value, quote ? "\"" : "");
	reply_len = sizeof(reply);
	wpagui->ctrlRequest(cmd, reply, &reply_len);
	return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
}


void NetworkConfig::encrChanged(const QString &)
{
}


void NetworkConfig::wepEnabled(bool enabled)
{
	wep0Edit->setEnabled(enabled);
	wep1Edit->setEnabled(enabled);
	wep2Edit->setEnabled(enabled);
	wep3Edit->setEnabled(enabled);
	wep0Radio->setEnabled(enabled);
	wep1Radio->setEnabled(enabled);
	wep2Radio->setEnabled(enabled);
	wep3Radio->setEnabled(enabled);
}


void NetworkConfig::writeWepKey(int network_id, QLineEdit *edit, int id)
{
	char buf[10];
	bool hex;
	const char *txt, *pos;
	size_t len;

	if (!edit->isEnabled() || edit->text().isEmpty())
		return;

	/*
	 * Assume hex key if only hex characters are present and length matches
	 * with 40, 104, or 128-bit key
	 */
	txt = edit->text().toAscii().constData();
	if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
		return;
	len = strlen(txt);
	if (len == 0)
		return;
	pos = txt;
	hex = true;
	while (*pos) {
		if (!((*pos >= '0' && *pos <= '9') ||
		      (*pos >= 'a' && *pos <= 'f') ||
		      (*pos >= 'A' && *pos <= 'F'))) {
			hex = false;
			break;
		}
		pos++;
	}
	if (hex && len != 10 && len != 26 && len != 32)
		hex = false;
	snprintf(buf, sizeof(buf), "wep_key%d", id);
	setNetworkParam(network_id, buf, txt, !hex);
}


static int key_value_isset(const char *reply, size_t reply_len)
{
    return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
}


void NetworkConfig::paramsFromConfig(int network_id)
{
	int i, res;

	edit_network_id = network_id;
	getEapCapa();

	char reply[1024], cmd[256], *pos;
	size_t reply_len;

	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
	    reply_len >= 2 && reply[0] == '"') {
		reply[reply_len] = '\0';
		pos = strchr(reply + 1, '"');
		if (pos)
			*pos = '\0';
		ssidEdit->setText(reply + 1);
	}

	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
	reply_len = sizeof(reply) - 1;
	int wpa = 0;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
		reply[reply_len] = '\0';
		if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
			wpa = 2;
		else if (strstr(reply, "WPA"))
			wpa = 1;
	}

	int auth = AUTH_NONE_OPEN, encr = 0;
	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
		reply[reply_len] = '\0';
		if (strstr(reply, "WPA-EAP"))
			auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
		else if (strstr(reply, "WPA-PSK"))
			auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
		else if (strstr(reply, "IEEE8021X")) {
			auth = AUTH_IEEE8021X;
			encr = 1;
		}
	}

	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
		reply[reply_len] = '\0';
		if (strstr(reply, "CCMP") && auth != AUTH_NONE_OPEN &&
		    auth != AUTH_NONE_WEP && auth != AUTH_NONE_WEP_SHARED)
			encr = 1;
		else if (strstr(reply, "TKIP"))
			encr = 0;
		else if (strstr(reply, "WEP"))
			encr = 1;
		else
			encr = 0;
	}

	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
	reply_len = sizeof(reply) - 1;
	res = wpagui->ctrlRequest(cmd, reply, &reply_len);
	if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
		reply[reply_len] = '\0';
		pos = strchr(reply + 1, '"');
		if (pos)
			*pos = '\0';
		pskEdit->setText(reply + 1);
	} else if (res >= 0 && key_value_isset(reply, reply_len)) {
		pskEdit->setText(WPA_GUI_KEY_DATA);
	}

	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
	    reply_len >= 2 && reply[0] == '"') {
		reply[reply_len] = '\0';
		pos = strchr(reply + 1, '"');
		if (pos)
			*pos = '\0';
		identityEdit->setText(reply + 1);
	}

	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
	reply_len = sizeof(reply) - 1;
	res = wpagui->ctrlRequest(cmd, reply, &reply_len);
	if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
		reply[reply_len] = '\0';
		pos = strchr(reply + 1, '"');
		if (pos)
			*pos = '\0';
		passwordEdit->setText(reply + 1);
	} else if (res >= 0 && key_value_isset(reply, reply_len)) {
		passwordEdit->setText(WPA_GUI_KEY_DATA);
	}

	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
	    reply_len >= 2 && reply[0] == '"') {
		reply[reply_len] = '\0';
		pos = strchr(reply + 1, '"');
		if (pos)
			*pos = '\0';
		cacertEdit->setText(reply + 1);
	}

	enum { NO_INNER, PEAP_INNER, TTLS_INNER, FAST_INNER } eap = NO_INNER;
	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
	    reply_len >= 1) {
		reply[reply_len] = '\0';
		for (i = 0; i < eapSelect->count(); i++) {
			if (eapSelect->itemText(i).compare(reply) == 0) {
				eapSelect->setCurrentIndex(i);
				if (strcmp(reply, "PEAP") == 0)
					eap = PEAP_INNER;
				else if (strcmp(reply, "TTLS") == 0)
					eap = TTLS_INNER;
				else if (strcmp(reply, "FAST") == 0)
					eap = FAST_INNER;
				break;
			}
		}
	}

	if (eap != NO_INNER) {
		snprintf(cmd, sizeof(cmd), "GET_NETWORK %d phase2",
			 network_id);
		reply_len = sizeof(reply) - 1;
		if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
		    reply_len >= 1) {
			reply[reply_len] = '\0';
			eapChanged(eapSelect->currentIndex());
		} else
			eap = NO_INNER;
	}

	char *val;
	val = reply + 1;
	while (*(val + 1))
		val++;
	if (*val == '"')
		*val = '\0';

	switch (eap) {
	case PEAP_INNER:
		if (strncmp(reply, "\"auth=", 6))
			break;
		val = reply + 2;
		memcpy(val, "EAP-", 4);
		break;
	case TTLS_INNER:
		if (strncmp(reply, "\"autheap=", 9) == 0) {
			val = reply + 5;
			memcpy(val, "EAP-", 4);
		} else if (strncmp(reply, "\"auth=", 6) == 0)
			val = reply + 6;
		break;
	case FAST_INNER:
		if (strncmp(reply, "\"auth=", 6))
			break;
		if (strcmp(reply + 6, "GTC auth=MSCHAPV2") == 0) {
			val = (char *) "GTC(auth) + MSCHAPv2(prov)";
			break;
		}
		val = reply + 2;
		memcpy(val, "EAP-", 4);
		break;
	case NO_INNER:
		break;
	}

	for (i = 0; i < phase2Select->count(); i++) {
		if (phase2Select->itemText(i).compare(val) == 0) {
			phase2Select->setCurrentIndex(i);
			break;
		}
	}

	for (i = 0; i < 4; i++) {
		QLineEdit *wepEdit;
		switch (i) {
		default:
		case 0:
			wepEdit = wep0Edit;
			break;
		case 1:
			wepEdit = wep1Edit;
			break;
		case 2:
			wepEdit = wep2Edit;
			break;
		case 3:
			wepEdit = wep3Edit;
			break;
		}
		snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d",
			 network_id, i);
		reply_len = sizeof(reply) - 1;
		res = wpagui->ctrlRequest(cmd, reply, &reply_len);
		if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
			reply[reply_len] = '\0';
			pos = strchr(reply + 1, '"');
			if (pos)
				*pos = '\0';
			if (auth == AUTH_NONE_OPEN || auth == AUTH_IEEE8021X) {
				if (auth == AUTH_NONE_OPEN)
					auth = AUTH_NONE_WEP;
				encr = 1;
			}

			wepEdit->setText(reply + 1);
		} else if (res >= 0 && key_value_isset(reply, reply_len)) {
			if (auth == AUTH_NONE_OPEN || auth == AUTH_IEEE8021X) {
				if (auth == AUTH_NONE_OPEN)
					auth = AUTH_NONE_WEP;
				encr = 1;
			}
			wepEdit->setText(WPA_GUI_KEY_DATA);
		}
	}

	if (auth == AUTH_NONE_WEP) {
		snprintf(cmd, sizeof(cmd), "GET_NETWORK %d auth_alg",
			 network_id);
		reply_len = sizeof(reply) - 1;
		if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
			reply[reply_len] = '\0';
			if (strcmp(reply, "SHARED") == 0)
				auth = AUTH_NONE_WEP_SHARED;
		}
	}

	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
	{
		reply[reply_len] = '\0';
		switch (atoi(reply)) {
		case 0:
			wep0Radio->setChecked(true);
			break;
		case 1:
			wep1Radio->setChecked(true);
			break;
		case 2:
			wep2Radio->setChecked(true);
			break;
		case 3:
			wep3Radio->setChecked(true);
			break;
		}
	}

	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d id_str", network_id);
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
	    reply_len >= 2 && reply[0] == '"') {
		reply[reply_len] = '\0';
		pos = strchr(reply + 1, '"');
		if (pos)
			*pos = '\0';
		idstrEdit->setText(reply + 1);
	}

	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d priority", network_id);
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
	{
		reply[reply_len] = '\0';
		prioritySpinBox->setValue(atoi(reply));
	}

	authSelect->setCurrentIndex(auth);
	authChanged(auth);
	encrSelect->setCurrentIndex(encr);
	wepEnabled(auth == AUTH_NONE_WEP || auth == AUTH_NONE_WEP_SHARED);

	removeButton->setEnabled(true);
	addButton->setText("Save");
}


void NetworkConfig::removeNetwork()
{
	char reply[10], cmd[256];
	size_t reply_len;

	if (QMessageBox::information(
		    this, "wpa_gui",
		    tr("This will permanently remove the network\n"
		       "from the configuration. Do you really want\n"
		       "to remove this network?"),
		    tr("Yes"), tr("No")) != 0)
		return;

	snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
	reply_len = sizeof(reply);
	wpagui->ctrlRequest(cmd, reply, &reply_len);
	if (strncmp(reply, "OK", 2) != 0) {
		QMessageBox::warning(this, "wpa_gui",
				     tr("Failed to remove network from "
					"wpa_supplicant\n"
					"configuration."));
	} else {
		wpagui->triggerUpdate();
		wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
	}

	close();
}


void NetworkConfig::newNetwork()
{
	new_network = true;
	getEapCapa();
}


void NetworkConfig::getEapCapa()
{
	char reply[256];
	size_t reply_len;

	if (wpagui == NULL)
		return;

	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
		return;
	reply[reply_len] = '\0';

	QString res(reply);
	QStringList types = res.split(QChar(' '));
	eapSelect->insertItems(-1, types);
}


void NetworkConfig::useWps()
{
	if (wpagui == NULL)
		return;
	wpagui->setBssFromScan(bssid);
	wpagui->wpsDialog();
	close();
}
