From e8fa6039f6ee3a0b0ed4d2741cca534ac04006a0 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Wed, 6 May 2009 13:23:41 +0300 Subject: [PATCH] WPS methods exported over DBus I've exported the methods wpsPbc, wpsReg and wpsPin (patch attached), so wpa_supplicant should be able to connect with WPS using the dbus interface. I couldn't test it well because the problem seems to be in my wireless card, a Broadcom BCM4328. At least it seems to do the same using both interfaces. With ndiswrapper driver the "wpsie" entry (thanks Dan!) didn't appear, and with the Broadcom wl driver it appears but I cannot associate using WPS. --- wpa_supplicant/ctrl_iface_dbus.c | 8 ++ wpa_supplicant/ctrl_iface_dbus.h | 9 ++ wpa_supplicant/ctrl_iface_dbus_handlers.c | 144 ++++++++++++++++++++++ wpa_supplicant/ctrl_iface_dbus_handlers.h | 11 ++ 4 files changed, 172 insertions(+) diff --git a/wpa_supplicant/ctrl_iface_dbus.c b/wpa_supplicant/ctrl_iface_dbus.c index 434f1a6a7..26a3e9dd8 100644 --- a/wpa_supplicant/ctrl_iface_dbus.c +++ b/wpa_supplicant/ctrl_iface_dbus.c @@ -545,6 +545,14 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection, reply = wpas_dbus_iface_set_blobs(message, wpa_s); else if (!strcmp(method, "removeBlobs")) reply = wpas_dbus_iface_remove_blobs(message, wpa_s); +#ifdef CONFIG_WPS + else if (!os_strcmp(method, "wpsPbc")) + reply = wpas_dbus_iface_wps_pbc(message, wpa_s); + else if (!os_strcmp(method, "wpsPin")) + reply = wpas_dbus_iface_wps_pin(message, wpa_s); + else if (!os_strcmp(method, "wpsReg")) + reply = wpas_dbus_iface_wps_reg(message, wpa_s); +#endif /* CONFIG_WPS */ } /* If the message was handled, send back the reply */ diff --git a/wpa_supplicant/ctrl_iface_dbus.h b/wpa_supplicant/ctrl_iface_dbus.h index 68919de02..8e9036d58 100644 --- a/wpa_supplicant/ctrl_iface_dbus.h +++ b/wpa_supplicant/ctrl_iface_dbus.h @@ -74,6 +74,15 @@ struct wps_credential; #define WPAS_ERROR_REMOVE_NETWORK_ERROR \ WPAS_DBUS_IFACE_INTERFACE ".RemoveNetworkError" +#ifdef CONFIG_WPS +#define WPAS_ERROR_WPS_PBC_ERROR \ + WPAS_DBUS_IFACE_INTERFACE ".WpsPbcError" +#define WPAS_ERROR_WPS_PIN_ERROR \ + WPAS_DBUS_IFACE_INTERFACE ".WpsPinError" +#define WPAS_ERROR_WPS_REG_ERROR \ + WPAS_DBUS_IFACE_INTERFACE ".WpsRegError" +#endif /* CONFIG_WPS */ + #define WPAS_DBUS_BSSID_FORMAT "%02x%02x%02x%02x%02x%02x" struct wpa_global; diff --git a/wpa_supplicant/ctrl_iface_dbus_handlers.c b/wpa_supplicant/ctrl_iface_dbus_handlers.c index 3fbe5d339..e9dd9a515 100644 --- a/wpa_supplicant/ctrl_iface_dbus_handlers.c +++ b/wpa_supplicant/ctrl_iface_dbus_handlers.c @@ -25,6 +25,7 @@ #include "ieee802_11_defs.h" #include "wpas_glue.h" #include "eapol_supp/eapol_supp_sm.h" +#include "wps_supplicant.h" extern int wpa_debug_level; extern int wpa_debug_show_keys; @@ -1460,3 +1461,146 @@ DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message, return wpas_dbus_new_success_reply(message); } + + +#ifdef CONFIG_WPS + +/** + * wpas_dbus_iface_wps_pbc - Request credentials using WPS PBC method + * @message: Pointer to incoming dbus message + * @wpa_s: %wpa_supplicant data structure + * Returns: A dbus message containing a UINT32 indicating success (1) or + * failure (0) + * + * Handler function for "wpsPbc" method call + */ +DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + char *arg_bssid = NULL; + u8 bssid[ETH_ALEN]; + int ret = 0; + + if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid, + DBUS_TYPE_INVALID)) + return wpas_dbus_new_invalid_opts_error(message, NULL); + + if (!os_strcmp(arg_bssid, "any")) + ret = wpas_wps_start_pbc(wpa_s, NULL); + else if (!hwaddr_aton(arg_bssid, bssid)) + ret = wpas_wps_start_pbc(wpa_s, bssid); + else { + return wpas_dbus_new_invalid_opts_error(message, + "Invalid BSSID"); + } + + if (ret < 0) { + return dbus_message_new_error(message, + WPAS_ERROR_WPS_PBC_ERROR, + "Could not start PBC " + "negotiation"); + } + + return wpas_dbus_new_success_reply(message); +} + + +/** + * wpas_dbus_iface_wps_pin - Establish the PIN number of the enrollee + * @message: Pointer to incoming dbus message + * @wpa_s: %wpa_supplicant data structure + * Returns: A dbus message containing a UINT32 indicating success (1) or + * failure (0) + * + * Handler function for "wpsPin" method call + */ +DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + char *arg_bssid; + char *pin = NULL; + u8 bssid[ETH_ALEN], *_bssid = NULL; + int ret = 0; + + if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid, + DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID)) + return wpas_dbus_new_invalid_opts_error(message, NULL); + + if (!os_strcmp(arg_bssid, "any")) + _bssid = NULL; + else if (!hwaddr_aton(arg_bssid, bssid)) + _bssid = bssid; + else { + return wpas_dbus_new_invalid_opts_error(message, + "Invalid BSSID"); + } + + if (os_strlen(pin) > 0) + ret = wpas_wps_start_pin(wpa_s, _bssid, pin); + else + ret = wpas_wps_start_pin(wpa_s, _bssid, NULL); + + if (ret < 0) { + return dbus_message_new_error(message, + WPAS_ERROR_WPS_PIN_ERROR, + "Could not init PIN"); + } + + reply = dbus_message_new_method_return(message); + if (reply == NULL) + return NULL; + + if (ret == 0) { + dbus_message_append_args(reply, DBUS_TYPE_STRING, &pin, + DBUS_TYPE_INVALID); + } else { + char npin[9]; + sprintf(npin, "%08d", ret); + dbus_message_append_args(reply, DBUS_TYPE_STRING, &npin, + DBUS_TYPE_INVALID); + } + return reply; +} + + +/** + * wpas_dbus_iface_wps_reg - Request credentials using the PIN of the AP + * @message: Pointer to incoming dbus message + * @wpa_s: %wpa_supplicant data structure + * Returns: A dbus message containing a UINT32 indicating success (1) or + * failure (0) + * + * Handler function for "wpsReg" method call + */ +DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + char *arg_bssid; + char *pin = NULL; + u8 bssid[ETH_ALEN]; + int ret = 0; + + if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid, + DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID)) + return wpas_dbus_new_invalid_opts_error(message, NULL); + + if (!os_strcmp(arg_bssid, "any")) + ret = wpas_wps_start_reg(wpa_s, NULL, pin); + else if (!hwaddr_aton(arg_bssid, bssid)) + ret = wpas_wps_start_reg(wpa_s, bssid, pin); + else { + return wpas_dbus_new_invalid_opts_error(message, + "Invalid BSSID"); + } + + if (ret < 0) { + return dbus_message_new_error(message, + WPAS_ERROR_WPS_PBC_ERROR, + "Could not request credentials"); + } + + return wpas_dbus_new_success_reply(message); +} + +#endif /* CONFIG_WPS */ diff --git a/wpa_supplicant/ctrl_iface_dbus_handlers.h b/wpa_supplicant/ctrl_iface_dbus_handlers.h index 2800520bf..0df5f3e7d 100644 --- a/wpa_supplicant/ctrl_iface_dbus_handlers.h +++ b/wpa_supplicant/ctrl_iface_dbus_handlers.h @@ -83,6 +83,17 @@ DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message, DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message, struct wpa_supplicant *wpa_s); +#ifdef CONFIG_WPS +DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message, + struct wpa_supplicant *wpa_s); +#endif /* CONFIG_WPS */ + #endif /* CONFIG_CTRL_IFACE_DBUS */ #endif /* CTRL_IFACE_DBUS_HANDLERS_H */