Branch data Line data Source code
1 : : /*
2 : : * WPA Supplicant / dbus-based control interface (WPS)
3 : : * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 : : * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
5 : : *
6 : : * This software may be distributed under the terms of the BSD license.
7 : : * See README for more details.
8 : : */
9 : :
10 : : #include "includes.h"
11 : :
12 : : #include "common.h"
13 : : #include "../config.h"
14 : : #include "../wpa_supplicant_i.h"
15 : : #include "../wps_supplicant.h"
16 : : #include "../driver_i.h"
17 : : #include "../ap.h"
18 : : #include "dbus_new_helpers.h"
19 : : #include "dbus_new.h"
20 : : #include "dbus_new_handlers.h"
21 : : #include "dbus_dict_helpers.h"
22 : :
23 : :
24 : : struct wps_start_params {
25 : : int role; /* 0 - not set, 1 - enrollee, 2 - registrar */
26 : : int type; /* 0 - not set, 1 - pin, 2 - pbc */
27 : : u8 *bssid;
28 : : char *pin;
29 : : u8 *p2p_dev_addr;
30 : : };
31 : :
32 : :
33 : 0 : static int wpas_dbus_handler_wps_role(DBusMessage *message,
34 : : DBusMessageIter *entry_iter,
35 : : struct wps_start_params *params,
36 : : DBusMessage **reply)
37 : : {
38 : : DBusMessageIter variant_iter;
39 : : char *val;
40 : :
41 : 0 : dbus_message_iter_recurse(entry_iter, &variant_iter);
42 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(&variant_iter) !=
43 : : DBUS_TYPE_STRING) {
44 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Role type, "
45 : : "string required");
46 : 0 : *reply = wpas_dbus_error_invalid_args(message,
47 : : "Role must be a string");
48 : 0 : return -1;
49 : : }
50 : 0 : dbus_message_iter_get_basic(&variant_iter, &val);
51 [ # # ]: 0 : if (os_strcmp(val, "enrollee") == 0)
52 : 0 : params->role = 1;
53 [ # # ]: 0 : else if (os_strcmp(val, "registrar") == 0)
54 : 0 : params->role = 2;
55 : : else {
56 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Uknown role %s", val);
57 : 0 : *reply = wpas_dbus_error_invalid_args(message, val);
58 : 0 : return -1;
59 : : }
60 : 0 : return 0;
61 : : }
62 : :
63 : :
64 : 0 : static int wpas_dbus_handler_wps_type(DBusMessage *message,
65 : : DBusMessageIter *entry_iter,
66 : : struct wps_start_params *params,
67 : : DBusMessage **reply)
68 : : {
69 : : DBusMessageIter variant_iter;
70 : : char *val;
71 : :
72 : 0 : dbus_message_iter_recurse(entry_iter, &variant_iter);
73 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(&variant_iter) !=
74 : : DBUS_TYPE_STRING) {
75 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Type type, "
76 : : "string required");
77 : 0 : *reply = wpas_dbus_error_invalid_args(message,
78 : : "Type must be a string");
79 : 0 : return -1;
80 : : }
81 : 0 : dbus_message_iter_get_basic(&variant_iter, &val);
82 [ # # ]: 0 : if (os_strcmp(val, "pin") == 0)
83 : 0 : params->type = 1;
84 [ # # ]: 0 : else if (os_strcmp(val, "pbc") == 0)
85 : 0 : params->type = 2;
86 : : else {
87 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Unknown type %s",
88 : : val);
89 : 0 : *reply = wpas_dbus_error_invalid_args(message, val);
90 : 0 : return -1;
91 : : }
92 : 0 : return 0;
93 : : }
94 : :
95 : :
96 : 0 : static int wpas_dbus_handler_wps_bssid(DBusMessage *message,
97 : : DBusMessageIter *entry_iter,
98 : : struct wps_start_params *params,
99 : : DBusMessage **reply)
100 : : {
101 : : DBusMessageIter variant_iter, array_iter;
102 : : int len;
103 : :
104 : 0 : dbus_message_iter_recurse(entry_iter, &variant_iter);
105 [ # # # # ]: 0 : if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY ||
106 : 0 : dbus_message_iter_get_element_type(&variant_iter) !=
107 : : DBUS_TYPE_BYTE) {
108 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Bssid type, "
109 : : "byte array required");
110 : 0 : *reply = wpas_dbus_error_invalid_args(
111 : : message, "Bssid must be a byte array");
112 : 0 : return -1;
113 : : }
114 : 0 : dbus_message_iter_recurse(&variant_iter, &array_iter);
115 : 0 : dbus_message_iter_get_fixed_array(&array_iter, ¶ms->bssid, &len);
116 [ # # ]: 0 : if (len != ETH_ALEN) {
117 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Stsrt - Wrong Bssid length "
118 : : "%d", len);
119 : 0 : *reply = wpas_dbus_error_invalid_args(message,
120 : : "Bssid is wrong length");
121 : 0 : return -1;
122 : : }
123 : 0 : return 0;
124 : : }
125 : :
126 : :
127 : 0 : static int wpas_dbus_handler_wps_pin(DBusMessage *message,
128 : : DBusMessageIter *entry_iter,
129 : : struct wps_start_params *params,
130 : : DBusMessage **reply)
131 : : {
132 : : DBusMessageIter variant_iter;
133 : :
134 : 0 : dbus_message_iter_recurse(entry_iter, &variant_iter);
135 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(&variant_iter) !=
136 : : DBUS_TYPE_STRING) {
137 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Pin type, "
138 : : "string required");
139 : 0 : *reply = wpas_dbus_error_invalid_args(message,
140 : : "Pin must be a string");
141 : 0 : return -1;
142 : : }
143 : 0 : dbus_message_iter_get_basic(&variant_iter, ¶ms->pin);
144 : 0 : return 0;
145 : : }
146 : :
147 : :
148 : : #ifdef CONFIG_P2P
149 : 0 : static int wpas_dbus_handler_wps_p2p_dev_addr(DBusMessage *message,
150 : : DBusMessageIter *entry_iter,
151 : : struct wps_start_params *params,
152 : : DBusMessage **reply)
153 : : {
154 : : DBusMessageIter variant_iter, array_iter;
155 : : int len;
156 : :
157 : 0 : dbus_message_iter_recurse(entry_iter, &variant_iter);
158 [ # # # # ]: 0 : if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY ||
159 : 0 : dbus_message_iter_get_element_type(&variant_iter) !=
160 : : DBUS_TYPE_BYTE) {
161 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong "
162 : : "P2PDeviceAddress type, byte array required");
163 : 0 : *reply = wpas_dbus_error_invalid_args(
164 : : message, "P2PDeviceAddress must be a byte array");
165 : 0 : return -1;
166 : : }
167 : 0 : dbus_message_iter_recurse(&variant_iter, &array_iter);
168 : 0 : dbus_message_iter_get_fixed_array(&array_iter, ¶ms->p2p_dev_addr,
169 : : &len);
170 [ # # ]: 0 : if (len != ETH_ALEN) {
171 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong "
172 : : "P2PDeviceAddress length %d", len);
173 : 0 : *reply = wpas_dbus_error_invalid_args(message,
174 : : "P2PDeviceAddress "
175 : : "has wrong length");
176 : 0 : return -1;
177 : : }
178 : 0 : return 0;
179 : : }
180 : : #endif /* CONFIG_P2P */
181 : :
182 : :
183 : 0 : static int wpas_dbus_handler_wps_start_entry(DBusMessage *message, char *key,
184 : : DBusMessageIter *entry_iter,
185 : : struct wps_start_params *params,
186 : : DBusMessage **reply)
187 : : {
188 [ # # ]: 0 : if (os_strcmp(key, "Role") == 0)
189 : 0 : return wpas_dbus_handler_wps_role(message, entry_iter,
190 : : params, reply);
191 [ # # ]: 0 : else if (os_strcmp(key, "Type") == 0)
192 : 0 : return wpas_dbus_handler_wps_type(message, entry_iter,
193 : : params, reply);
194 [ # # ]: 0 : else if (os_strcmp(key, "Bssid") == 0)
195 : 0 : return wpas_dbus_handler_wps_bssid(message, entry_iter,
196 : : params, reply);
197 [ # # ]: 0 : else if (os_strcmp(key, "Pin") == 0)
198 : 0 : return wpas_dbus_handler_wps_pin(message, entry_iter,
199 : : params, reply);
200 : : #ifdef CONFIG_P2P
201 [ # # ]: 0 : else if (os_strcmp(key, "P2PDeviceAddress") == 0)
202 : 0 : return wpas_dbus_handler_wps_p2p_dev_addr(message, entry_iter,
203 : : params, reply);
204 : : #endif /* CONFIG_P2P */
205 : :
206 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - unknown key %s", key);
207 : 0 : *reply = wpas_dbus_error_invalid_args(message, key);
208 : 0 : return -1;
209 : : }
210 : :
211 : :
212 : : /**
213 : : * wpas_dbus_handler_wps_start - Start WPS configuration
214 : : * @message: Pointer to incoming dbus message
215 : : * @wpa_s: %wpa_supplicant data structure
216 : : * Returns: DBus message dictionary on success or DBus error on failure
217 : : *
218 : : * Handler for "Start" method call. DBus dictionary argument contains
219 : : * information about role (enrollee or registrar), authorization method
220 : : * (pin or push button) and optionally pin and bssid. Returned message
221 : : * has a dictionary argument which may contain newly generated pin (optional).
222 : : */
223 : 0 : DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
224 : : struct wpa_supplicant *wpa_s)
225 : : {
226 : 0 : DBusMessage *reply = NULL;
227 : : DBusMessageIter iter, dict_iter, entry_iter;
228 : : struct wps_start_params params;
229 : : char *key;
230 : 0 : char npin[9] = { '\0' };
231 : : int ret;
232 : :
233 : 0 : os_memset(¶ms, 0, sizeof(params));
234 : 0 : dbus_message_iter_init(message, &iter);
235 : :
236 : 0 : dbus_message_iter_recurse(&iter, &dict_iter);
237 [ # # ]: 0 : while (dbus_message_iter_get_arg_type(&dict_iter) ==
238 : : DBUS_TYPE_DICT_ENTRY) {
239 : 0 : dbus_message_iter_recurse(&dict_iter, &entry_iter);
240 : :
241 : 0 : dbus_message_iter_get_basic(&entry_iter, &key);
242 : 0 : dbus_message_iter_next(&entry_iter);
243 : :
244 [ # # ]: 0 : if (wpas_dbus_handler_wps_start_entry(message, key,
245 : : &entry_iter,
246 : : ¶ms, &reply))
247 : 0 : return reply;
248 : :
249 : 0 : dbus_message_iter_next(&dict_iter);
250 : : }
251 : :
252 [ # # ]: 0 : if (params.role == 0) {
253 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Role not specified");
254 : 0 : return wpas_dbus_error_invalid_args(message,
255 : : "Role not specified");
256 [ # # ][ # # ]: 0 : } else if (params.role == 1 && params.type == 0) {
257 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Type not specified");
258 : 0 : return wpas_dbus_error_invalid_args(message,
259 : : "Type not specified");
260 [ # # ][ # # ]: 0 : } else if (params.role == 2 && params.pin == NULL) {
261 : 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Pin required for "
262 : : "registrar role");
263 : 0 : return wpas_dbus_error_invalid_args(
264 : : message, "Pin required for registrar role.");
265 : : }
266 : :
267 [ # # ]: 0 : if (params.role == 2)
268 : 0 : ret = wpas_wps_start_reg(wpa_s, params.bssid, params.pin,
269 : : NULL);
270 [ # # ]: 0 : else if (params.type == 1) {
271 : : #ifdef CONFIG_AP
272 [ # # ]: 0 : if (wpa_s->ap_iface)
273 : 0 : ret = wpa_supplicant_ap_wps_pin(wpa_s,
274 : 0 : params.bssid,
275 : 0 : params.pin,
276 : : npin, sizeof(npin), 0);
277 : : else
278 : : #endif /* CONFIG_AP */
279 : : {
280 : 0 : ret = wpas_wps_start_pin(wpa_s, params.bssid,
281 : 0 : params.pin, 0,
282 : : DEV_PW_DEFAULT);
283 [ # # ]: 0 : if (ret > 0)
284 : 0 : os_snprintf(npin, sizeof(npin), "%08d", ret);
285 : : }
286 : : } else {
287 : : #ifdef CONFIG_AP
288 [ # # ]: 0 : if (wpa_s->ap_iface)
289 : 0 : ret = wpa_supplicant_ap_wps_pbc(wpa_s,
290 : 0 : params.bssid,
291 : 0 : params.p2p_dev_addr);
292 : : else
293 : : #endif /* CONFIG_AP */
294 : 0 : ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
295 : : }
296 : :
297 [ # # ]: 0 : if (ret < 0) {
298 [ # # ][ # # ]: 0 : wpa_printf(MSG_DEBUG, "dbus: WPS.Start wpas_wps_failed in "
299 : : "role %s and key %s",
300 : 0 : (params.role == 1 ? "enrollee" : "registrar"),
301 : 0 : (params.type == 0 ? "" :
302 [ # # ]: 0 : (params.type == 1 ? "pin" : "pbc")));
303 : 0 : return wpas_dbus_error_unknown_error(message,
304 : : "WPS start failed");
305 : : }
306 : :
307 : 0 : reply = dbus_message_new_method_return(message);
308 [ # # ]: 0 : if (!reply) {
309 : 0 : return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
310 : : NULL);
311 : : }
312 : :
313 : 0 : dbus_message_iter_init_append(reply, &iter);
314 [ # # ]: 0 : if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
315 : 0 : dbus_message_unref(reply);
316 : 0 : return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
317 : : NULL);
318 : : }
319 : :
320 [ # # ]: 0 : if (os_strlen(npin) > 0) {
321 [ # # ]: 0 : if (!wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) {
322 : 0 : dbus_message_unref(reply);
323 : 0 : return dbus_message_new_error(message,
324 : : DBUS_ERROR_NO_MEMORY,
325 : : NULL);
326 : : }
327 : : }
328 : :
329 [ # # ]: 0 : if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
330 : 0 : dbus_message_unref(reply);
331 : 0 : return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
332 : : NULL);
333 : : }
334 : :
335 : 0 : return reply;
336 : : }
337 : :
338 : :
339 : : /**
340 : : * wpas_dbus_getter_process_credentials - Check if credentials are processed
341 : : * @message: Pointer to incoming dbus message
342 : : * @wpa_s: %wpa_supplicant data structure
343 : : * Returns: TRUE on success, FALSE on failure
344 : : *
345 : : * Getter for "ProcessCredentials" property. Returns returned boolean will be
346 : : * true if wps_cred_processing configuration field is not equal to 1 or false
347 : : * if otherwise.
348 : : */
349 : 0 : dbus_bool_t wpas_dbus_getter_process_credentials(DBusMessageIter *iter,
350 : : DBusError *error,
351 : : void *user_data)
352 : : {
353 : 0 : struct wpa_supplicant *wpa_s = user_data;
354 : 0 : dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1);
355 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
356 : : &process, error);
357 : : }
358 : :
359 : :
360 : : /**
361 : : * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
362 : : * @iter: Pointer to incoming dbus message iter
363 : : * @error: Location to store error on failure
364 : : * @user_data: Function specific data
365 : : * Returns: TRUE on success, FALSE on failure
366 : : *
367 : : * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
368 : : * if boolean argument is true or on 1 if otherwise.
369 : : */
370 : 0 : dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter,
371 : : DBusError *error,
372 : : void *user_data)
373 : : {
374 : 0 : struct wpa_supplicant *wpa_s = user_data;
375 : : dbus_bool_t process_credentials, old_pc;
376 : :
377 [ # # ]: 0 : if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
378 : : &process_credentials))
379 : 0 : return FALSE;
380 : :
381 : 0 : old_pc = (wpa_s->conf->wps_cred_processing != 1);
382 [ # # ]: 0 : wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
383 : :
384 [ # # ]: 0 : if ((wpa_s->conf->wps_cred_processing != 1) != old_pc)
385 : 0 : wpa_dbus_mark_property_changed(wpa_s->global->dbus,
386 : 0 : wpa_s->dbus_new_path,
387 : : WPAS_DBUS_NEW_IFACE_WPS,
388 : : "ProcessCredentials");
389 : :
390 : 0 : return TRUE;
391 : : }
|