dbus_new_handlers_wps.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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. /**
  25. * wpas_dbus_handler_wps_start - Start WPS configuration
  26. * @message: Pointer to incoming dbus message
  27. * @wpa_s: %wpa_supplicant data structure
  28. * Returns: DBus message dictionary on success or DBus error on failure
  29. *
  30. * Handler for "Start" method call. DBus dictionary argument contains
  31. * information about role (enrollee or registrar), authorization method
  32. * (pin or push button) and optionally pin and bssid. Returned message
  33. * has a dictionary argument which may contain newly generated pin (optional).
  34. */
  35. DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
  36. struct wpa_supplicant *wpa_s)
  37. {
  38. DBusMessage * reply = NULL;
  39. DBusMessageIter iter, dict_iter, entry_iter, variant_iter, array_iter;
  40. char *key, *val;
  41. int role = 0; /* 0 - not set, 1 - enrollee, 2 - registrar */
  42. int type = 0; /* 0 - not set, 1 - pin, 2 - pbc */
  43. u8 *bssid = NULL;
  44. char *pin = NULL, npin[9] = { '\0' };
  45. int len, ret;
  46. dbus_message_iter_init(message, &iter);
  47. dbus_message_iter_recurse(&iter, &dict_iter);
  48. while (dbus_message_iter_get_arg_type(&dict_iter) ==
  49. DBUS_TYPE_DICT_ENTRY) {
  50. dbus_message_iter_recurse(&dict_iter, &entry_iter);
  51. dbus_message_iter_get_basic(&entry_iter, &key);
  52. dbus_message_iter_next(&entry_iter);
  53. if (os_strcmp(key, "Role") == 0) {
  54. dbus_message_iter_recurse(&entry_iter, &variant_iter);
  55. if (dbus_message_iter_get_arg_type(&variant_iter) !=
  56. DBUS_TYPE_STRING) {
  57. wpa_printf(MSG_DEBUG,
  58. "wpas_dbus_handler_wps_start"
  59. "[dbus]: "
  60. "wrong Role type. string required");
  61. return wpas_dbus_error_invald_args(
  62. message, "Role must be a string");
  63. }
  64. dbus_message_iter_get_basic(&variant_iter, &val);
  65. if (os_strcmp(val, "enrollee") == 0)
  66. role = 1;
  67. else if (os_strcmp(val, "registrar") == 0)
  68. role = 2;
  69. else {
  70. wpa_printf(MSG_DEBUG,
  71. "wpas_dbus_handler_wps_start[dbus]: "
  72. "unknown role %s", val);
  73. return wpas_dbus_error_invald_args(message,
  74. val);
  75. }
  76. } else if (strcmp(key, "Type") == 0) {
  77. dbus_message_iter_recurse(&entry_iter, &variant_iter);
  78. if (dbus_message_iter_get_arg_type(&variant_iter) !=
  79. DBUS_TYPE_STRING) {
  80. wpa_printf(MSG_DEBUG,
  81. "wpas_dbus_handler_wps_start[dbus]: "
  82. "wrong Type type. string required");
  83. return wpas_dbus_error_invald_args(
  84. message, "Type must be a string");
  85. }
  86. dbus_message_iter_get_basic(&variant_iter, &val);
  87. if (os_strcmp(val, "pin") == 0)
  88. type = 1;
  89. else if (os_strcmp(val, "pbc") == 0)
  90. type = 2;
  91. else {
  92. wpa_printf(MSG_DEBUG,
  93. "wpas_dbus_handler_wps_start[dbus]: "
  94. "unknown type %s", val);
  95. return wpas_dbus_error_invald_args(message,
  96. val);
  97. }
  98. } else if (strcmp(key, "Bssid") == 0) {
  99. dbus_message_iter_recurse(&entry_iter, &variant_iter);
  100. if (dbus_message_iter_get_arg_type(&variant_iter) !=
  101. DBUS_TYPE_ARRAY ||
  102. dbus_message_iter_get_element_type(&variant_iter) !=
  103. DBUS_TYPE_ARRAY) {
  104. wpa_printf(MSG_DEBUG,
  105. "wpas_dbus_handler_wps_start[dbus]: "
  106. "wrong Bssid type. byte array required");
  107. return wpas_dbus_error_invald_args(
  108. message, "Bssid must be a byte array");
  109. }
  110. dbus_message_iter_recurse(&variant_iter, &array_iter);
  111. dbus_message_iter_get_fixed_array(&array_iter, &bssid,
  112. &len);
  113. if (len != ETH_ALEN) {
  114. wpa_printf(MSG_DEBUG,
  115. "wpas_dbus_handler_wps_start[dbus]: "
  116. "wrong Bssid length %d", len);
  117. return wpas_dbus_error_invald_args(
  118. message, "Bssid is wrong length");
  119. }
  120. }
  121. else if (os_strcmp(key, "Pin") == 0) {
  122. dbus_message_iter_recurse(&entry_iter, &variant_iter);
  123. if (dbus_message_iter_get_arg_type(&variant_iter) !=
  124. DBUS_TYPE_STRING) {
  125. wpa_printf(MSG_DEBUG,
  126. "wpas_dbus_handler_wps_start[dbus]: "
  127. "wrong Pin type. string required");
  128. return wpas_dbus_error_invald_args(
  129. message, "Pin must be a string");
  130. }
  131. dbus_message_iter_get_basic(&variant_iter, &pin);
  132. } else {
  133. wpa_printf(MSG_DEBUG,
  134. "wpas_dbus_handler_wps_start[dbus]: "
  135. "unknown key %s", key);
  136. return wpas_dbus_error_invald_args(message, key);
  137. }
  138. dbus_message_iter_next(&dict_iter);
  139. }
  140. if (role == 0) {
  141. wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
  142. "Role not specified");
  143. return wpas_dbus_error_invald_args(message,
  144. "Role not specified");
  145. }
  146. else if (role == 1 && type == 0) {
  147. wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
  148. "Type not specified");
  149. return wpas_dbus_error_invald_args(message,
  150. "Type not specified");
  151. }
  152. else if (role == 2 && pin == NULL) {
  153. wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
  154. "Pin required for registrar role.");
  155. return wpas_dbus_error_invald_args(
  156. message, "Pin required for registrar role.");
  157. }
  158. if (role == 2)
  159. ret = wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
  160. else if (type == 1) {
  161. ret = wpas_wps_start_pin(wpa_s, bssid, pin);
  162. if (ret > 0)
  163. os_snprintf(npin, sizeof(npin), "%08d", ret);
  164. } else
  165. ret = wpas_wps_start_pbc(wpa_s, bssid);
  166. if (ret < 0) {
  167. wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
  168. "wpas_wps_failed in role %s and key %s.",
  169. (role == 1 ? "enrollee" : "registrar"),
  170. (type == 0 ? "" : (type == 1 ? "pin" : "pbc")));
  171. return wpas_dbus_error_unknown_error(message,
  172. "wps start failed");
  173. }
  174. reply = dbus_message_new_method_return(message);
  175. if (!reply) {
  176. return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
  177. NULL);
  178. }
  179. dbus_message_iter_init_append(reply, &iter);
  180. if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
  181. dbus_message_unref(reply);
  182. return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
  183. NULL);
  184. }
  185. if (os_strlen(npin) > 0) {
  186. if (!wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) {
  187. dbus_message_unref(reply);
  188. return dbus_message_new_error(message,
  189. DBUS_ERROR_NO_MEMORY,
  190. NULL);
  191. }
  192. }
  193. if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
  194. dbus_message_unref(reply);
  195. return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
  196. NULL);
  197. }
  198. return reply;
  199. }
  200. /**
  201. * wpas_dbus_getter_process_credentials - Check if credentials are processed
  202. * @message: Pointer to incoming dbus message
  203. * @wpa_s: %wpa_supplicant data structure
  204. * Returns: DBus message with a boolean on success or DBus error on failure
  205. *
  206. * Getter for "ProcessCredentials" property. Returns returned boolean will be
  207. * true if wps_cred_processing configuration field is not equal to 1 or false
  208. * if otherwise.
  209. */
  210. DBusMessage * wpas_dbus_getter_process_credentials(
  211. DBusMessage *message, struct wpa_supplicant *wpa_s)
  212. {
  213. dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1);
  214. return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
  215. &process);
  216. }
  217. /**
  218. * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
  219. * @message: Pointer to incoming dbus message
  220. * @wpa_s: %wpa_supplicant data structure
  221. * Returns: NULL on success or DBus error on failure
  222. *
  223. * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
  224. * if boolean argument is true or on 1 if otherwise.
  225. */
  226. DBusMessage * wpas_dbus_setter_process_credentials(
  227. DBusMessage *message, struct wpa_supplicant *wpa_s)
  228. {
  229. DBusMessage *reply = NULL;
  230. dbus_bool_t process_credentials, old_pc;
  231. reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32,
  232. &process_credentials);
  233. if (reply)
  234. return reply;
  235. old_pc = (wpa_s->conf->wps_cred_processing != 1);
  236. wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
  237. if ((wpa_s->conf->wps_cred_processing != 1) != old_pc)
  238. wpa_dbus_signal_property_changed(
  239. wpa_s->global->dbus,
  240. (WPADBusPropertyAccessor)
  241. wpas_dbus_getter_process_credentials,
  242. wpa_s, wpa_s->dbus_new_path,
  243. WPAS_DBUS_NEW_IFACE_WPS,
  244. "ProcessCredentials");
  245. return NULL;
  246. }