You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dbus_new_handlers_wps.c 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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 program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * Alternatively, this software may be distributed under the terms of BSD
  11. * license.
  12. *
  13. * See README and COPYING for more details.
  14. */
  15. #include "includes.h"
  16. #include "common.h"
  17. #include "../config.h"
  18. #include "../wpa_supplicant_i.h"
  19. #include "../wps_supplicant.h"
  20. #include "dbus_new_helpers.h"
  21. #include "dbus_new.h"
  22. #include "dbus_new_handlers.h"
  23. #include "dbus_dict_helpers.h"
  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. };
  30. static int wpas_dbus_handler_wps_role(DBusMessage *message,
  31. DBusMessageIter *entry_iter,
  32. struct wps_start_params *params,
  33. DBusMessage **reply)
  34. {
  35. DBusMessageIter variant_iter;
  36. char *val;
  37. dbus_message_iter_recurse(entry_iter, &variant_iter);
  38. if (dbus_message_iter_get_arg_type(&variant_iter) !=
  39. DBUS_TYPE_STRING) {
  40. wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Role type, "
  41. "string required");
  42. *reply = wpas_dbus_error_invalid_args(message,
  43. "Role must be a string");
  44. return -1;
  45. }
  46. dbus_message_iter_get_basic(&variant_iter, &val);
  47. if (os_strcmp(val, "enrollee") == 0)
  48. params->role = 1;
  49. else if (os_strcmp(val, "registrar") == 0)
  50. params->role = 2;
  51. else {
  52. wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Uknown role %s", val);
  53. *reply = wpas_dbus_error_invalid_args(message, val);
  54. return -1;
  55. }
  56. return 0;
  57. }
  58. static int wpas_dbus_handler_wps_type(DBusMessage *message,
  59. DBusMessageIter *entry_iter,
  60. struct wps_start_params *params,
  61. DBusMessage **reply)
  62. {
  63. DBusMessageIter variant_iter;
  64. char *val;
  65. dbus_message_iter_recurse(entry_iter, &variant_iter);
  66. if (dbus_message_iter_get_arg_type(&variant_iter) !=
  67. DBUS_TYPE_STRING) {
  68. wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Type type, "
  69. "string required");
  70. *reply = wpas_dbus_error_invalid_args(message,
  71. "Type must be a string");
  72. return -1;
  73. }
  74. dbus_message_iter_get_basic(&variant_iter, &val);
  75. if (os_strcmp(val, "pin") == 0)
  76. params->type = 1;
  77. else if (os_strcmp(val, "pbc") == 0)
  78. params->type = 2;
  79. else {
  80. wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Unknown type %s",
  81. val);
  82. *reply = wpas_dbus_error_invalid_args(message, val);
  83. return -1;
  84. }
  85. return 0;
  86. }
  87. static int wpas_dbus_handler_wps_bssid(DBusMessage *message,
  88. DBusMessageIter *entry_iter,
  89. struct wps_start_params *params,
  90. DBusMessage **reply)
  91. {
  92. DBusMessageIter variant_iter, array_iter;
  93. int len;
  94. dbus_message_iter_recurse(entry_iter, &variant_iter);
  95. if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY ||
  96. dbus_message_iter_get_element_type(&variant_iter) !=
  97. DBUS_TYPE_BYTE) {
  98. wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Bssid type, "
  99. "byte array required");
  100. *reply = wpas_dbus_error_invalid_args(
  101. message, "Bssid must be a byte array");
  102. return -1;
  103. }
  104. dbus_message_iter_recurse(&variant_iter, &array_iter);
  105. dbus_message_iter_get_fixed_array(&array_iter, &params->bssid, &len);
  106. if (len != ETH_ALEN) {
  107. wpa_printf(MSG_DEBUG, "dbus: WPS.Stsrt - Wrong Bssid length "
  108. "%d", len);
  109. *reply = wpas_dbus_error_invalid_args(message,
  110. "Bssid is wrong length");
  111. return -1;
  112. }
  113. return 0;
  114. }
  115. static int wpas_dbus_handler_wps_pin(DBusMessage *message,
  116. DBusMessageIter *entry_iter,
  117. struct wps_start_params *params,
  118. DBusMessage **reply)
  119. {
  120. DBusMessageIter variant_iter;
  121. dbus_message_iter_recurse(entry_iter, &variant_iter);
  122. if (dbus_message_iter_get_arg_type(&variant_iter) !=
  123. DBUS_TYPE_STRING) {
  124. wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Pin type, "
  125. "string required");
  126. *reply = wpas_dbus_error_invalid_args(message,
  127. "Pin must be a string");
  128. return -1;
  129. }
  130. dbus_message_iter_get_basic(&variant_iter, &params->pin);
  131. return 0;
  132. }
  133. static int wpas_dbus_handler_wps_start_entry(DBusMessage *message, char *key,
  134. DBusMessageIter *entry_iter,
  135. struct wps_start_params *params,
  136. DBusMessage **reply)
  137. {
  138. if (os_strcmp(key, "Role") == 0)
  139. return wpas_dbus_handler_wps_role(message, entry_iter,
  140. params, reply);
  141. else if (os_strcmp(key, "Type") == 0)
  142. return wpas_dbus_handler_wps_type(message, entry_iter,
  143. params, reply);
  144. else if (os_strcmp(key, "Bssid") == 0)
  145. return wpas_dbus_handler_wps_bssid(message, entry_iter,
  146. params, reply);
  147. else if (os_strcmp(key, "Pin") == 0)
  148. return wpas_dbus_handler_wps_pin(message, entry_iter,
  149. params, reply);
  150. wpa_printf(MSG_DEBUG, "dbus: WPS.Start - unknown key %s", key);
  151. *reply = wpas_dbus_error_invalid_args(message, key);
  152. return -1;
  153. }
  154. /**
  155. * wpas_dbus_handler_wps_start - Start WPS configuration
  156. * @message: Pointer to incoming dbus message
  157. * @wpa_s: %wpa_supplicant data structure
  158. * Returns: DBus message dictionary on success or DBus error on failure
  159. *
  160. * Handler for "Start" method call. DBus dictionary argument contains
  161. * information about role (enrollee or registrar), authorization method
  162. * (pin or push button) and optionally pin and bssid. Returned message
  163. * has a dictionary argument which may contain newly generated pin (optional).
  164. */
  165. DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
  166. struct wpa_supplicant *wpa_s)
  167. {
  168. DBusMessage *reply = NULL;
  169. DBusMessageIter iter, dict_iter, entry_iter;
  170. struct wps_start_params params;
  171. char *key;
  172. char npin[9] = { '\0' };
  173. int ret;
  174. os_memset(&params, 0, sizeof(params));
  175. dbus_message_iter_init(message, &iter);
  176. dbus_message_iter_recurse(&iter, &dict_iter);
  177. while (dbus_message_iter_get_arg_type(&dict_iter) ==
  178. DBUS_TYPE_DICT_ENTRY) {
  179. dbus_message_iter_recurse(&dict_iter, &entry_iter);
  180. dbus_message_iter_get_basic(&entry_iter, &key);
  181. dbus_message_iter_next(&entry_iter);
  182. if (wpas_dbus_handler_wps_start_entry(message, key,
  183. &entry_iter,
  184. &params, &reply))
  185. return reply;
  186. dbus_message_iter_next(&dict_iter);
  187. }
  188. if (params.role == 0) {
  189. wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Role not specified");
  190. return wpas_dbus_error_invalid_args(message,
  191. "Role not specified");
  192. } else if (params.role == 1 && params.type == 0) {
  193. wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Type not specified");
  194. return wpas_dbus_error_invalid_args(message,
  195. "Type not specified");
  196. } else if (params.role == 2 && params.pin == NULL) {
  197. wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Pin required for "
  198. "registrar role");
  199. return wpas_dbus_error_invalid_args(
  200. message, "Pin required for registrar role.");
  201. }
  202. if (params.role == 2)
  203. ret = wpas_wps_start_reg(wpa_s, params.bssid, params.pin,
  204. NULL);
  205. else if (params.type == 1) {
  206. ret = wpas_wps_start_pin(wpa_s, params.bssid, params.pin, 0,
  207. DEV_PW_DEFAULT);
  208. if (ret > 0)
  209. os_snprintf(npin, sizeof(npin), "%08d", ret);
  210. } else
  211. ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
  212. if (ret < 0) {
  213. wpa_printf(MSG_DEBUG, "dbus: WPS.Start wpas_wps_failed in "
  214. "role %s and key %s",
  215. (params.role == 1 ? "enrollee" : "registrar"),
  216. (params.type == 0 ? "" :
  217. (params.type == 1 ? "pin" : "pbc")));
  218. return wpas_dbus_error_unknown_error(message,
  219. "WPS start failed");
  220. }
  221. reply = dbus_message_new_method_return(message);
  222. if (!reply) {
  223. return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
  224. NULL);
  225. }
  226. dbus_message_iter_init_append(reply, &iter);
  227. if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
  228. dbus_message_unref(reply);
  229. return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
  230. NULL);
  231. }
  232. if (os_strlen(npin) > 0) {
  233. if (!wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) {
  234. dbus_message_unref(reply);
  235. return dbus_message_new_error(message,
  236. DBUS_ERROR_NO_MEMORY,
  237. NULL);
  238. }
  239. }
  240. if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
  241. dbus_message_unref(reply);
  242. return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
  243. NULL);
  244. }
  245. return reply;
  246. }
  247. /**
  248. * wpas_dbus_getter_process_credentials - Check if credentials are processed
  249. * @message: Pointer to incoming dbus message
  250. * @wpa_s: %wpa_supplicant data structure
  251. * Returns: DBus message with a boolean on success or DBus error on failure
  252. *
  253. * Getter for "ProcessCredentials" property. Returns returned boolean will be
  254. * true if wps_cred_processing configuration field is not equal to 1 or false
  255. * if otherwise.
  256. */
  257. DBusMessage * wpas_dbus_getter_process_credentials(
  258. DBusMessage *message, struct wpa_supplicant *wpa_s)
  259. {
  260. dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1);
  261. return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
  262. &process);
  263. }
  264. /**
  265. * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
  266. * @message: Pointer to incoming dbus message
  267. * @wpa_s: %wpa_supplicant data structure
  268. * Returns: NULL on success or DBus error on failure
  269. *
  270. * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
  271. * if boolean argument is true or on 1 if otherwise.
  272. */
  273. DBusMessage * wpas_dbus_setter_process_credentials(
  274. DBusMessage *message, struct wpa_supplicant *wpa_s)
  275. {
  276. DBusMessage *reply = NULL;
  277. dbus_bool_t process_credentials, old_pc;
  278. reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
  279. &process_credentials);
  280. if (reply)
  281. return reply;
  282. old_pc = (wpa_s->conf->wps_cred_processing != 1);
  283. wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
  284. if ((wpa_s->conf->wps_cred_processing != 1) != old_pc)
  285. wpa_dbus_mark_property_changed(wpa_s->global->dbus,
  286. wpa_s->dbus_new_path,
  287. WPAS_DBUS_NEW_IFACE_WPS,
  288. "ProcessCredentials");
  289. return NULL;
  290. }