/*
 * 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::WindowFlags)
	: 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().toLocal8Bit().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().toLocal8Bit().constData(),
		   WPA_GUI_KEY_DATA) != 0)
		setNetworkParam(id, "psk",
				pskEdit->text().toLocal8Bit().constData(),
				psklen != 64);
	if (eapSelect->isEnabled()) {
		const char *eap =
			eapSelect->currentText().toLocal8Bit().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).
					 toLocal8Bit().constData());
		} else if (eap.compare("TTLS") == 0) {
			if (inner.startsWith("EAP-"))
				snprintf(phase2, sizeof(phase2), "autheap=%s",
					 inner.right(inner.size() - 4).
					 toLocal8Bit().constData());
			else
				snprintf(phase2, sizeof(phase2), "auth=%s",
					 inner.toLocal8Bit().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).
					 toLocal8Bit().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().toLocal8Bit().constData(),
				true);
	else
		setNetworkParam(id, "identity", "NULL", false);
	if (passwordEdit->isEnabled() && passwordEdit->text().length() > 0 &&
	    strcmp(passwordEdit->text().toLocal8Bit().constData(),
		   WPA_GUI_KEY_DATA) != 0)
		setNetworkParam(id, "password",
				passwordEdit->text().toLocal8Bit().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().toLocal8Bit().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().toLocal8Bit().constData(),
				true);
	else
		setNetworkParam(id, "id_str", "NULL", false);

	if (prioritySpinBox->isEnabled()) {
		QString prio;
		prio = prio.setNum(prioritySpinBox->value());
		setNetworkParam(id, "priority", prio.toLocal8Bit().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().toLocal8Bit().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();
}
