• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * wpa_gui - AddInterface class
3  * Copyright (c) 2008, Jouni Malinen <j@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 "wpa_ctrl.h"
17 
18 #include <QMessageBox>
19 
20 #include "wpagui.h"
21 #include "addinterface.h"
22 
23 #ifdef CONFIG_NATIVE_WINDOWS
24 #include <windows.h>
25 
26 #ifndef WPA_KEY_ROOT
27 #define WPA_KEY_ROOT HKEY_LOCAL_MACHINE
28 #endif
29 #ifndef WPA_KEY_PREFIX
30 #define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant")
31 #endif
32 #endif /* CONFIG_NATIVE_WINDOWS */
33 
34 
AddInterface(WpaGui * _wpagui,QWidget * parent)35 AddInterface::AddInterface(WpaGui *_wpagui, QWidget *parent)
36 	: QDialog(parent), wpagui(_wpagui)
37 {
38 	setWindowTitle("Select network interface to add");
39 	resize(400, 200);
40 	vboxLayout = new QVBoxLayout(this);
41 
42 	interfaceWidget = new QTreeWidget(this);
43 	interfaceWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
44 	interfaceWidget->setUniformRowHeights(true);
45 	interfaceWidget->setSortingEnabled(true);
46 	interfaceWidget->setColumnCount(3);
47 	interfaceWidget->headerItem()->setText(0, "driver");
48 	interfaceWidget->headerItem()->setText(1, "interface");
49 	interfaceWidget->headerItem()->setText(2, "description");
50 	interfaceWidget->setItemsExpandable(FALSE);
51 	interfaceWidget->setRootIsDecorated(FALSE);
52 	vboxLayout->addWidget(interfaceWidget);
53 
54 	connect(interfaceWidget,
55 		SIGNAL(itemActivated(QTreeWidgetItem *, int)), this,
56 		SLOT(interfaceSelected(QTreeWidgetItem *)));
57 
58 	addInterfaces();
59 }
60 
61 
addInterfaces()62 void AddInterface::addInterfaces()
63 {
64 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
65 	struct wpa_ctrl *ctrl;
66 	int ret;
67 	char buf[2048];
68 	size_t len;
69 
70 	ctrl = wpa_ctrl_open(NULL);
71 	if (ctrl == NULL)
72 		return;
73 
74 	len = sizeof(buf) - 1;
75 	ret = wpa_ctrl_request(ctrl, "INTERFACE_LIST", 14, buf, &len, NULL);
76 	if (ret < 0) {
77 		wpa_ctrl_close(ctrl);
78 		return;
79 	}
80 	buf[len] = '\0';
81 
82 	wpa_ctrl_close(ctrl);
83 
84 	QString ifaces(buf);
85 	QStringList lines = ifaces.split(QRegExp("\\n"));
86 	for (QStringList::Iterator it = lines.begin();
87 	     it != lines.end(); it++) {
88 		QStringList arg = (*it).split(QChar('\t'));
89 		if (arg.size() < 3)
90 			continue;
91 		QTreeWidgetItem *item = new QTreeWidgetItem(interfaceWidget);
92 		if (!item)
93 			break;
94 
95 		item->setText(0, arg[0]);
96 		item->setText(1, arg[1]);
97 		item->setText(2, arg[2]);
98 	}
99 
100 	interfaceWidget->resizeColumnToContents(0);
101 	interfaceWidget->resizeColumnToContents(1);
102 	interfaceWidget->resizeColumnToContents(2);
103 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
104 }
105 
106 
107 #ifdef CONFIG_NATIVE_WINDOWS
addRegistryInterface(const QString & ifname)108 bool AddInterface::addRegistryInterface(const QString &ifname)
109 {
110 	HKEY hk, ihk;
111 	LONG ret;
112 	int id, tmp;
113 	TCHAR name[10];
114 	DWORD val, i;
115 
116 	ret = RegOpenKeyEx(WPA_KEY_ROOT, WPA_KEY_PREFIX TEXT("\\interfaces"),
117 			   0, KEY_ENUMERATE_SUB_KEYS | KEY_CREATE_SUB_KEY,
118 			   &hk);
119 	if (ret != ERROR_SUCCESS)
120 		return false;
121 
122 	id = -1;
123 
124 	for (i = 0; ; i++) {
125 		TCHAR name[255];
126 		DWORD namelen;
127 
128 		namelen = 255;
129 		ret = RegEnumKeyEx(hk, i, name, &namelen, NULL, NULL, NULL,
130 				   NULL);
131 
132 		if (ret == ERROR_NO_MORE_ITEMS)
133 			break;
134 
135 		if (ret != ERROR_SUCCESS)
136 			break;
137 
138 		if (namelen >= 255)
139 			namelen = 255 - 1;
140 		name[namelen] = '\0';
141 
142 #ifdef UNICODE
143 		QString s((QChar *) name, namelen);
144 #else /* UNICODE */
145 		QString s(name);
146 #endif /* UNICODE */
147 		tmp = s.toInt();
148 		if (tmp > id)
149 			id = tmp;
150 	}
151 
152 	id += 1;
153 
154 #ifdef UNICODE
155 	wsprintf(name, L"%04d", id);
156 #else /* UNICODE */
157 	os_snprintf(name, sizeof(name), "%04d", id);
158 #endif /* UNICODE */
159 	ret = RegCreateKeyEx(hk, name, 0, NULL, 0, KEY_WRITE, NULL, &ihk,
160 			     NULL);
161 	RegCloseKey(hk);
162 	if (ret != ERROR_SUCCESS)
163 		return false;
164 
165 #ifdef UNICODE
166 	RegSetValueEx(ihk, TEXT("adapter"), 0, REG_SZ,
167 		      (LPBYTE) ifname.unicode(),
168 		      (ifname.length() + 1) * sizeof(TCHAR));
169 
170 #else /* UNICODE */
171 	RegSetValueEx(ihk, TEXT("adapter"), 0, REG_SZ,
172 		      (LPBYTE) ifname.toLocal8Bit(), ifname.length() + 1);
173 #endif /* UNICODE */
174 	RegSetValueEx(ihk, TEXT("config"), 0, REG_SZ,
175 		      (LPBYTE) TEXT("default"), 8 * sizeof(TCHAR));
176 	RegSetValueEx(ihk, TEXT("ctrl_interface"), 0, REG_SZ,
177 		      (LPBYTE) TEXT(""), 1 * sizeof(TCHAR));
178 	val = 1;
179 	RegSetValueEx(ihk, TEXT("skip_on_error"), 0, REG_DWORD, (LPBYTE) &val,
180 		      sizeof(val));
181 
182 	RegCloseKey(ihk);
183 	return true;
184 }
185 #endif /* CONFIG_NATIVE_WINDOWS */
186 
187 
interfaceSelected(QTreeWidgetItem * sel)188 void AddInterface::interfaceSelected(QTreeWidgetItem *sel)
189 {
190 	if (!sel)
191 		return;
192 
193 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
194 	struct wpa_ctrl *ctrl;
195 	int ret;
196 	char buf[20], cmd[256];
197 	size_t len;
198 
199 	/*
200 	 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
201 	 * <driver_param>TAB<bridge_name>
202 	 */
203 	snprintf(cmd, sizeof(cmd),
204 		 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
205 		 sel->text(1).toAscii().constData(),
206 		 "default",
207 		 sel->text(0).toAscii().constData(),
208 		 "yes", "", "");
209 	cmd[sizeof(cmd) - 1] = '\0';
210 
211 	ctrl = wpa_ctrl_open(NULL);
212 	if (ctrl == NULL)
213 		return;
214 
215 	len = sizeof(buf) - 1;
216 	ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL);
217 	wpa_ctrl_close(ctrl);
218 
219 	if (ret < 0) {
220 		QMessageBox::warning(this, "wpa_gui",
221 				     "Add interface command could not be "
222 				     "completed.");
223 		return;
224 	}
225 
226 	buf[len] = '\0';
227 	if (buf[0] != 'O' || buf[1] != 'K') {
228 		QMessageBox::warning(this, "wpa_gui",
229 				     "Failed to add the interface.");
230 		return;
231 	}
232 
233 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
234 
235 #ifdef CONFIG_NATIVE_WINDOWS
236 	if (!addRegistryInterface(sel->text(1))) {
237 		QMessageBox::information(this, "wpa_gui",
238 					 "Failed to add the interface into "
239 					 "registry.");
240 	}
241 #endif /* CONFIG_NATIVE_WINDOWS */
242 
243 	wpagui->selectAdapter(sel->text(1));
244 	close();
245 }
246